From 9b6bd309023c2733f603603d39e5c2bdc66a0f83 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sun, 29 Jan 2023 01:22:10 -0500
Subject: [PATCH 01/35] Support diffing syntax, import elements (#58)
---
TODO.md | 4 +--
src/proto_file.py | 12 +++++--
src/proto_import.py | 66 ++++++++++++++++++++++++++++++++++++-
src/proto_node.py | 4 +++
src/proto_string_literal.py | 3 ++
src/proto_syntax.py | 20 ++++++++++-
test/BUILD.bazel | 9 +++++
test/proto_file_test.py | 11 +++++++
test/proto_import_test.py | 45 ++++++++++++++++++++++++-
test/proto_syntax_test.py | 20 ++++++++++-
10 files changed, 186 insertions(+), 8 deletions(-)
create mode 100644 test/proto_file_test.py
diff --git a/TODO.md b/TODO.md
index 932562d..99b3afb 100644
--- a/TODO.md
+++ b/TODO.md
@@ -60,8 +60,8 @@
- [x] Normalizing
- [ ] Complete diffs
- [ ] Proto file-level diffs
- - [ ] Syntax changes
- - [ ] Import changes
+ - [x] Syntax changes
+ - [x] Import changes
- [ ] Package changes
- [ ] Option changes
- [ ] Enum-level diffs
diff --git a/src/proto_file.py b/src/proto_file.py
index d02291b..b208e36 100644
--- a/src/proto_file.py
+++ b/src/proto_file.py
@@ -1,5 +1,7 @@
+from typing import Optional
+
from src.proto_import import ProtoImport
-from src.proto_node import ProtoNode
+from src.proto_node import ProtoNode, ProtoNodeDiff
from src.proto_option import ProtoOption
from src.proto_package import ProtoPackage
from src.proto_syntax import ProtoSyntax
@@ -18,7 +20,7 @@ def imports(self) -> list[ProtoImport]:
return [node for node in self.nodes if isinstance(node, ProtoImport)]
@property
- def package(self) -> ProtoPackage:
+ def package(self) -> Optional[ProtoPackage]:
return next(node for node in self.nodes if isinstance(node, ProtoPackage))
@property
@@ -36,3 +38,9 @@ def serialize(self) -> str:
serialized_parts.append(node.serialize())
return "\n".join(serialized_parts)
+
+ def diff(self, other: "ProtoFile") -> list[ProtoNodeDiff]:
+ diffs = []
+ diffs.extend(ProtoSyntax.diff(self.syntax, other.syntax))
+ diffs.extend(ProtoImport.diff(self.imports, other.imports))
+ return [d for d in diffs if d is not None]
diff --git a/src/proto_import.py b/src/proto_import.py
index 1c03c02..dc00a32 100644
--- a/src/proto_import.py
+++ b/src/proto_import.py
@@ -1,6 +1,6 @@
from typing import Optional
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
from src.proto_string_literal import ProtoStringLiteral
@@ -25,6 +25,13 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
+ def __dict__(self) -> dict:
+ return {
+ "path": self.path.serialize(),
+ "weak": self.weak,
+ "public": self.public,
+ }
+
def normalize(self) -> "ProtoImport":
return self
@@ -68,3 +75,60 @@ def serialize(self) -> str:
parts.append("public")
parts.append(f"{self.path.serialize()};")
return " ".join(parts)
+
+ @staticmethod
+ def diff(
+ left: list["ProtoImport"], right: list["ProtoImport"]
+ ) -> list["ProtoNodeDiff"]:
+ diffs = []
+ left_names = set(i.path for i in left)
+ right_names = set(i.path for i in right)
+ for name in left_names - right_names:
+ diffs.append(ProtoImportAdded(next(i for i in left if i.path == name)))
+ for name in right_names - left_names:
+ diffs.append(ProtoImportRemoved(next(i for i in right if i.path == name)))
+ for name in left_names & right_names:
+ left_import = next(i for i in left if i.path == name)
+ right_import = next(i for i in right if i.path == name)
+ if left_import.weak and not right_import.weak:
+ diffs.append(ProtoImportMadeWeak(right_import))
+ if not left_import.weak and right_import.weak:
+ diffs.append(ProtoImportMadeNonWeak(right_import))
+ if left_import.public and not right_import.public:
+ diffs.append(ProtoImportMadePublic(right_import))
+ if not left_import.public and right_import.public:
+ diffs.append(ProtoImportMadeNonPublic(right_import))
+
+ return diffs
+
+
+class ProtoImportAdded(ProtoNodeDiff):
+ def __init__(self, proto_import: ProtoImport):
+ self.proto_import = proto_import
+
+ def __eq__(self, other: "ProtoImportAdded") -> bool:
+ return self.proto_import == other.proto_import
+
+
+class ProtoImportRemoved(ProtoImportAdded):
+ pass
+
+
+class ProtoImportMadeWeak(ProtoImportAdded):
+ pass
+
+
+class ProtoImportMadeWeak(ProtoImportAdded):
+ pass
+
+
+class ProtoImportMadeNonWeak(ProtoImportAdded):
+ pass
+
+
+class ProtoImportMadePublic(ProtoImportAdded):
+ pass
+
+
+class ProtoImportMadeNonPublic(ProtoImportAdded):
+ pass
diff --git a/src/proto_node.py b/src/proto_node.py
index de8685f..05310eb 100644
--- a/src/proto_node.py
+++ b/src/proto_node.py
@@ -26,3 +26,7 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
+
+
+class ProtoNodeDiff(abc.ABC):
+ pass
diff --git a/src/proto_string_literal.py b/src/proto_string_literal.py
index b9a4b64..7336b0f 100644
--- a/src/proto_string_literal.py
+++ b/src/proto_string_literal.py
@@ -19,6 +19,9 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
+ def __hash__(self):
+ return hash(str(self))
+
def normalize(self) -> "ProtoStringLiteral":
return self
diff --git a/src/proto_syntax.py b/src/proto_syntax.py
index 7e00991..25109c7 100644
--- a/src/proto_syntax.py
+++ b/src/proto_syntax.py
@@ -1,7 +1,7 @@
from enum import Enum
from typing import Optional
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
from src.proto_string_literal import ProtoStringLiteral
@@ -23,6 +23,9 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
+ def __dict__(self) -> dict:
+ return {"syntax": self.syntax.serialize()}
+
def normalize(self) -> "ProtoSyntax":
return self
@@ -50,3 +53,18 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
def serialize(self) -> str:
return f"syntax = {self.syntax.serialize()};"
+
+ @staticmethod
+ def diff(left: "ProtoSyntax", right: "ProtoSyntax") -> list["ProtoNodeDiff"]:
+ if left == right:
+ return []
+ return [ProtoSyntaxChanged(left, right)]
+
+
+class ProtoSyntaxChanged(ProtoNodeDiff):
+ def __init__(self, left: ProtoStringLiteral, right: ProtoStringLiteral):
+ self.left = left
+ self.right = right
+
+ def __eq__(self, other: "ProtoSyntaxChanged") -> bool:
+ return self.left == other.left and self.right == other.right
diff --git a/test/BUILD.bazel b/test/BUILD.bazel
index ceea7c1..b538aae 100644
--- a/test/BUILD.bazel
+++ b/test/BUILD.bazel
@@ -103,6 +103,7 @@ py_test(
srcs = ["proto_import_test.py"],
deps = [
"//src:proto_import",
+ "//src:proto_string_literal",
],
)
@@ -213,6 +214,14 @@ py_test(
],
)
+py_test(
+ name = "proto_file_test",
+ srcs = ["proto_file_test.py"],
+ deps = [
+ "//src:proto_file",
+ ],
+)
+
sh_test(
name = "parser_binary_test",
srcs = ["parser_binary_test.sh"],
diff --git a/test/proto_file_test.py b/test/proto_file_test.py
new file mode 100644
index 0000000..1bbf1cd
--- /dev/null
+++ b/test/proto_file_test.py
@@ -0,0 +1,11 @@
+import unittest
+
+from src.proto_file import ProtoFile
+
+
+class ProtoFileTest(unittest.TestCase):
+ pass
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/test/proto_import_test.py b/test/proto_import_test.py
index 0f74495..bf43205 100644
--- a/test/proto_import_test.py
+++ b/test/proto_import_test.py
@@ -1,7 +1,14 @@
import unittest
from textwrap import dedent
-from src.proto_import import ProtoImport
+from src.proto_import import (
+ ProtoImport,
+ ProtoImportAdded,
+ ProtoImportMadeNonWeak,
+ ProtoImportMadePublic,
+ ProtoImportRemoved,
+)
+from src.proto_string_literal import ProtoStringLiteral
class ImportTest(unittest.TestCase):
@@ -128,6 +135,42 @@ def test_public_mixed_imports(self):
third_parsed_import.node.serialize(), 'import public "bat.proto";'
)
+ def test_diff_same_path_simple(self):
+ pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ pf2 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ self.assertEqual(ProtoImport.diff([pf1], [pf2]), [])
+
+ def test_diff_added_path_simple(self):
+ pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ self.assertEqual(ProtoImport.diff([pf1], []), [ProtoImportAdded(pf1)])
+
+ def test_diff_removed_path_simple(self):
+ pf2 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ self.assertEqual(ProtoImport.diff([], [pf2]), [ProtoImportRemoved(pf2)])
+
+ def test_diff_different_path_simple(self):
+ pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ pf2 = ProtoImport(ProtoStringLiteral("path/to/some/other.proto"))
+ self.assertEqual(
+ ProtoImport.diff([pf1], [pf2]),
+ [ProtoImportAdded(pf1), ProtoImportRemoved(pf2)],
+ )
+
+ def test_diff_changed_optional_attributes(self):
+ pf1 = ProtoImport(
+ ProtoStringLiteral("path/to/some.proto"), weak=False, public=True
+ )
+ pf2 = ProtoImport(
+ ProtoStringLiteral("path/to/some.proto"), weak=True, public=False
+ )
+ self.assertEqual(
+ ProtoImport.diff([pf1], [pf2]),
+ [
+ ProtoImportMadeNonWeak(pf2),
+ ProtoImportMadePublic(pf2),
+ ],
+ )
+
if __name__ == "__main__":
unittest.main()
diff --git a/test/proto_syntax_test.py b/test/proto_syntax_test.py
index 1d2aae7..6abfda1 100644
--- a/test/proto_syntax_test.py
+++ b/test/proto_syntax_test.py
@@ -1,7 +1,7 @@
import unittest
from src.proto_string_literal import ProtoStringLiteral
-from src.proto_syntax import ProtoSyntax, ProtoSyntaxType
+from src.proto_syntax import ProtoSyntax, ProtoSyntaxChanged
class SyntaxTest(unittest.TestCase):
@@ -75,6 +75,24 @@ def test_syntax_malformed(self):
with self.assertRaises(ValueError):
ProtoSyntax.match("syntax = proton")
+ def test_diff_empty_same_syntax_returns_empty(self):
+ pf1 = ProtoSyntax(ProtoStringLiteral("proto3"))
+ pf2 = ProtoSyntax(ProtoStringLiteral("proto3"))
+ self.assertEqual(ProtoSyntax.diff(pf1, pf2), [])
+
+ def test_diff_empty_different_syntax_returns_syntax_diff(self):
+ pf1 = ProtoSyntax(ProtoStringLiteral("proto3"))
+ pf2 = ProtoSyntax(ProtoStringLiteral("proto2"))
+ self.assertEqual(
+ ProtoSyntax.diff(pf1, pf2),
+ [
+ ProtoSyntaxChanged(
+ ProtoSyntax(ProtoStringLiteral("proto3")),
+ ProtoSyntax(ProtoStringLiteral("proto2")),
+ )
+ ],
+ )
+
if __name__ == "__main__":
unittest.main()
From 8b6fd051c4b553b656bc8156e7f64469687d1375 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sun, 29 Jan 2023 01:41:47 -0500
Subject: [PATCH 02/35] Update README.md (#59)
---
README.md | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 5fec8d4..bd8333d 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,35 @@
This is a Python-based protobuf parser. It is intended to serve as a reference implementation and is _not_ production-ready.
+![Build status](https://github.com/shaldengeki/py_proto/actions/workflows/main.yml/badge.svg)
+
+## Usage
+
+Right now, the primary way to use this as a library in your Bazelified Python code.
+
+Mount this repo in your Bazel workspace, then add `@py_proto//src:parser` as a dependency:
+```
+py_library(
+ name = "your_python_code",
+ # ...
+ deps = [
+ "@py_proto//src:parser",
+ ]
+)
+```
+
+Then, in your Python code, use the parser:
+```python
+from src.parser import ParseError, Parser
+with open("your.proto", "r") as proto_file:
+ parsed_proto = Parser.loads(proto_file.read())
+
+print(parsed_proto.syntax)
+```
+
## Development
-We support building & running via Bazel.
+We support building & running via Bazel. See the `TODO.md` for what's on the roadmap.
### Bazel
From 2eb9b4a16af913024064ad6961312581fba8a372 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Fri, 10 Feb 2023 21:02:49 -0500
Subject: [PATCH 03/35] Support diffs of package changes (#60)
---
TODO.md | 2 +-
src/proto_file.py | 1 +
src/proto_package.py | 37 ++++++++++++++++++++++++++++++-
test/proto_package_test.py | 45 +++++++++++++++++++++++++++++++++++++-
4 files changed, 82 insertions(+), 3 deletions(-)
diff --git a/TODO.md b/TODO.md
index 99b3afb..a93cb74 100644
--- a/TODO.md
+++ b/TODO.md
@@ -62,7 +62,7 @@
- [ ] Proto file-level diffs
- [x] Syntax changes
- [x] Import changes
- - [ ] Package changes
+ - [x] Package changes
- [ ] Option changes
- [ ] Enum-level diffs
- [ ] Additions/removals
diff --git a/src/proto_file.py b/src/proto_file.py
index b208e36..01c53e2 100644
--- a/src/proto_file.py
+++ b/src/proto_file.py
@@ -43,4 +43,5 @@ def diff(self, other: "ProtoFile") -> list[ProtoNodeDiff]:
diffs = []
diffs.extend(ProtoSyntax.diff(self.syntax, other.syntax))
diffs.extend(ProtoImport.diff(self.imports, other.imports))
+ diffs.extend(ProtoPackage.diff(self.package, other.package))
return [d for d in diffs if d is not None]
diff --git a/src/proto_package.py b/src/proto_package.py
index d44d5ee..c4da2c0 100644
--- a/src/proto_package.py
+++ b/src/proto_package.py
@@ -1,6 +1,6 @@
from typing import Optional
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
class ProtoPackage(ProtoNode):
@@ -48,3 +48,38 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
def serialize(self) -> str:
return f"package {self.package};"
+
+ @staticmethod
+ def diff(left: "ProtoPackage", right: "ProtoPackage") -> list["ProtoNodeDiff"]:
+ if left == right:
+ return []
+ elif left is None and right is not None:
+ return [ProtoPackageAdded(right)]
+ elif left is not None and right is None:
+ return [ProtoPackageRemoved(left)]
+ return [ProtoPackageChanged(left, right)]
+
+
+class ProtoPackageChanged(ProtoNodeDiff):
+ def __init__(self, left: str, right: str):
+ self.left = left
+ self.right = right
+
+ def __eq__(self, other: "ProtoPackageChanged") -> bool:
+ return self.left == other.left and self.right == other.right
+
+
+class ProtoPackageAdded(ProtoNodeDiff):
+ def __init__(self, left: str):
+ self.left = left
+
+ def __eq__(self, other: "ProtoPackageAdded") -> bool:
+ return self.left == other.left
+
+
+class ProtoPackageRemoved(ProtoNodeDiff):
+ def __init__(self, right: str):
+ self.right = right
+
+ def __eq__(self, other: "ProtoPackageRemoved") -> bool:
+ return self.right == other.right
diff --git a/test/proto_package_test.py b/test/proto_package_test.py
index 491708f..0225c19 100644
--- a/test/proto_package_test.py
+++ b/test/proto_package_test.py
@@ -1,7 +1,12 @@
import unittest
from textwrap import dedent
-from src.proto_package import ProtoPackage
+from src.proto_package import (
+ ProtoPackage,
+ ProtoPackageAdded,
+ ProtoPackageChanged,
+ ProtoPackageRemoved,
+)
class PackageTest(unittest.TestCase):
@@ -55,6 +60,44 @@ def test_package_malformed(self):
with self.assertRaises(ValueError):
ProtoPackage.match("packagefoo.bar;")
+ def test_diff_same_package_returns_empty(self):
+ pp1 = ProtoPackage("my.awesome.package")
+ pp2 = ProtoPackage("my.awesome.package")
+ self.assertEqual(ProtoPackage.diff(pp1, pp2), [])
+
+ def test_diff_different_package_returns_package_diff(self):
+ pp1 = ProtoPackage("my.awesome.package")
+ pp2 = ProtoPackage("my.other.awesome.package")
+ self.assertEqual(
+ ProtoPackage.diff(pp1, pp2),
+ [
+ ProtoPackageChanged(
+ ProtoPackage("my.awesome.package"),
+ ProtoPackage("my.other.awesome.package"),
+ )
+ ],
+ )
+
+ def test_diff_package_added(self):
+ pp1 = None
+ pp2 = ProtoPackage("my.new.package")
+ self.assertEqual(
+ ProtoPackage.diff(pp1, pp2),
+ [
+ ProtoPackageAdded(ProtoPackage("my.new.package")),
+ ],
+ )
+
+ def test_diff_package_removed(self):
+ pp1 = ProtoPackage("my.old.package")
+ pp2 = None
+ self.assertEqual(
+ ProtoPackage.diff(pp1, pp2),
+ [
+ ProtoPackageRemoved(ProtoPackage("my.old.package")),
+ ],
+ )
+
if __name__ == "__main__":
unittest.main()
From c00880e6d782b1d693fe3f42b6033dd79ef0b40b Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sat, 11 Feb 2023 01:32:44 -0500
Subject: [PATCH 04/35] Add support for proto option diffs (#61)
---
TODO.md | 2 +-
src/proto_identifier.py | 3 +
src/proto_option.py | 90 ++++++++-
src/proto_package.py | 6 +-
test/proto_option_test.py | 376 ++++++++++++++++++++++++++++++++++++-
test/proto_package_test.py | 8 +-
6 files changed, 475 insertions(+), 10 deletions(-)
diff --git a/TODO.md b/TODO.md
index a93cb74..0d937af 100644
--- a/TODO.md
+++ b/TODO.md
@@ -63,7 +63,7 @@
- [x] Syntax changes
- [x] Import changes
- [x] Package changes
- - [ ] Option changes
+ - [x] Option changes
- [ ] Enum-level diffs
- [ ] Additions/removals
- [ ] Option changes
diff --git a/src/proto_identifier.py b/src/proto_identifier.py
index 6dd6164..cc55aaf 100644
--- a/src/proto_identifier.py
+++ b/src/proto_identifier.py
@@ -20,6 +20,9 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
+ def __hash__(self):
+ return hash(str(self))
+
def normalize(self) -> "ProtoIdentifier":
return self
diff --git a/src/proto_option.py b/src/proto_option.py
index 000a39c..e86e360 100644
--- a/src/proto_option.py
+++ b/src/proto_option.py
@@ -6,7 +6,7 @@
ProtoFullIdentifier,
ProtoIdentifier,
)
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
class ProtoOption(ProtoNode):
@@ -23,6 +23,9 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
+ def __hash__(self):
+ return hash(str(self))
+
def normalize(self) -> "ProtoOption":
return self
@@ -91,3 +94,88 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
def serialize(self) -> str:
return f"option {self.name.serialize()} = {self.value.serialize()};"
+
+ @staticmethod
+ def diff(left: "ProtoOption", right: "ProtoOption") -> list["ProtoNodeDiff"]:
+ if left is None and right is not None:
+ return [ProtoOptionAdded(right)]
+ elif left is not None and right is None:
+ return [ProtoOptionRemoved(left)]
+ elif left is None and right is None:
+ return []
+ elif left.name != right.name:
+ return []
+ elif left == right:
+ return []
+ return [ProtoOptionValueChanged(left.name, left.value, right.value)]
+
+ @staticmethod
+ def diff_sets(
+ left: list["ProtoOption"], right: list["ProtoOption"]
+ ) -> list["ProtoNodeDiff"]:
+ diffs = []
+ left_names = set(o.name.identifier for o in left)
+ right_names = set(o.name.identifier for o in right)
+ for name in left_names - right_names:
+ diffs.append(
+ ProtoOptionAdded(next(i for i in left if i.name.identifier == name))
+ )
+ for name in right_names - left_names:
+ diffs.append(
+ ProtoOptionRemoved(next(i for i in right if i.name.identifier == name))
+ )
+ for name in left_names & right_names:
+ left_option = next(i for i in left if i.name.identifier == name)
+ right_option = next(i for i in right if i.name.identifier == name)
+ diffs.extend(ProtoOption.diff(left_option, right_option))
+
+ return diffs
+
+
+class ProtoOptionValueChanged(ProtoNodeDiff):
+ def __init__(self, name: ProtoIdentifier, left: str, right: str):
+ self.name = name
+ self.left = left
+ self.right = right
+
+ def __eq__(self, other: "ProtoOptionValueChanged") -> bool:
+ return (
+ isinstance(other, ProtoOptionValueChanged)
+ and self.name == other.name
+ and self.left == other.left
+ and self.right == other.right
+ )
+
+ def __str__(self) -> str:
+ return f""
+
+ def __repr__(self) -> str:
+ return str(self)
+
+
+class ProtoOptionAdded(ProtoNodeDiff):
+ def __init__(self, left: str):
+ self.left = left
+
+ def __eq__(self, other: "ProtoOptionAdded") -> bool:
+ return isinstance(other, ProtoOptionAdded) and self.left == other.left
+
+ def __str__(self) -> str:
+ return f""
+
+ def __repr__(self) -> str:
+ return str(self)
+
+
+class ProtoOptionRemoved(ProtoNodeDiff):
+ def __init__(self, right: str):
+ self.right = right
+
+ def __eq__(self, other: "ProtoOptionRemoved") -> bool:
+ return isinstance(other, ProtoOptionRemoved) and self.right == other.right
+
+ def __str__(self) -> str:
+ return f""
+
+ def __repr__(self) -> str:
+ return str(self)
diff --git a/src/proto_package.py b/src/proto_package.py
index c4da2c0..569ee2c 100644
--- a/src/proto_package.py
+++ b/src/proto_package.py
@@ -53,10 +53,10 @@ def serialize(self) -> str:
def diff(left: "ProtoPackage", right: "ProtoPackage") -> list["ProtoNodeDiff"]:
if left == right:
return []
- elif left is None and right is not None:
- return [ProtoPackageAdded(right)]
elif left is not None and right is None:
- return [ProtoPackageRemoved(left)]
+ return [ProtoPackageAdded(left)]
+ elif left is None and right is not None:
+ return [ProtoPackageRemoved(right)]
return [ProtoPackageChanged(left, right)]
diff --git a/test/proto_option_test.py b/test/proto_option_test.py
index 6d353fc..caf20ed 100644
--- a/test/proto_option_test.py
+++ b/test/proto_option_test.py
@@ -5,11 +5,19 @@
from src.proto_float import ProtoFloat, ProtoFloatSign
from src.proto_identifier import ProtoFullIdentifier, ProtoIdentifier
from src.proto_int import ProtoInt, ProtoIntSign
-from src.proto_option import ProtoOption
+from src.proto_option import (
+ ProtoOption,
+ ProtoOptionAdded,
+ ProtoOptionRemoved,
+ ProtoOptionValueChanged,
+)
from src.proto_string_literal import ProtoStringLiteral
class OptionTest(unittest.TestCase):
+
+ maxDiff = None
+
def test_string_option(self):
string_option = ProtoOption.match("option foo = 'test value';")
self.assertEqual(string_option.node.name, ProtoIdentifier("foo"))
@@ -192,6 +200,372 @@ def test_float_option(self):
ProtoConstant(ProtoFloat(float(120), ProtoFloatSign.NEGATIVE)),
)
+ def test_diff_same_option_returns_empty(self):
+ po1 = ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ po2 = ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ self.assertEqual(ProtoOption.diff(po1, po2), [])
+
+ def test_diff_different_option_name_returns_empty(self):
+ po1 = ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ po2 = ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ self.assertEqual(ProtoOption.diff(po1, po2), [])
+
+ def test_diff_different_option_value_returns_option_diff(self):
+ po1 = ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ po2 = ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("other value")),
+ )
+ self.assertEqual(
+ ProtoOption.diff(po1, po2),
+ [
+ ProtoOptionValueChanged(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ ProtoConstant(ProtoStringLiteral("other value")),
+ )
+ ],
+ )
+
+ def test_diff_option_added(self):
+ po1 = None
+ po2 = ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ self.assertEqual(
+ ProtoOption.diff(po1, po2),
+ [
+ ProtoOptionAdded(
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ ),
+ ],
+ )
+
+ def test_diff_option_removed(self):
+ po1 = ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ po2 = None
+ self.assertEqual(
+ ProtoOption.diff(po1, po2),
+ [
+ ProtoOptionRemoved(
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ ),
+ ],
+ )
+
+ def test_diff_sets_empty_returns_empty(self):
+ set1 = []
+ set2 = []
+ self.assertEqual(ProtoOption.diff_sets(set1, set2), [])
+
+ def test_diff_sets_no_change(self):
+ set1 = [
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ ),
+ ]
+ self.assertEqual(ProtoOption.diff_sets(set1, set1), [])
+
+ def test_diff_sets_all_removed(self):
+ set1 = []
+ set2 = [
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ ),
+ ]
+ diff = ProtoOption.diff_sets(set1, set2)
+
+ self.assertIn(
+ ProtoOptionRemoved(
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOptionRemoved(
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ )
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOptionRemoved(
+ ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ )
+ ),
+ diff,
+ )
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_all_added(self):
+ set1 = [
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ ),
+ ]
+ set2 = []
+ diff = ProtoOption.diff_sets(set1, set2)
+
+ self.assertIn(
+ ProtoOptionAdded(
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOptionAdded(
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ )
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOptionAdded(
+ ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ )
+ ),
+ diff,
+ )
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_mutually_exclusive(self):
+ set1 = [
+ ProtoOption(
+ ProtoIdentifier("some.custom.option.but.not.prior"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("ruby_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("other.option.but.stil.not.prior"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ ),
+ ]
+ set2 = [
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ ),
+ ]
+
+ diff = ProtoOption.diff_sets(set1, set2)
+
+ self.assertIn(
+ ProtoOptionAdded(
+ ProtoOption(
+ ProtoIdentifier("some.custom.option.but.not.prior"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOptionAdded(
+ ProtoOption(
+ ProtoIdentifier("other.option.but.stil.not.prior"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ )
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoOptionAdded(
+ ProtoOption(
+ ProtoIdentifier("ruby_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ )
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoOptionRemoved(
+ ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ )
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoOptionRemoved(
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoOptionRemoved(
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ )
+ ),
+ diff,
+ )
+
+ self.assertEqual(6, len(diff))
+
+ def test_diff_sets_overlap(self):
+ set1 = [
+ ProtoOption(
+ ProtoIdentifier("some.custom.option.but.not.prior"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.bat")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("other.option.but.stil.not.prior"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ ),
+ ]
+ set2 = [
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ ),
+ ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ ),
+ ]
+
+ diff = ProtoOption.diff_sets(set1, set2)
+
+ self.assertIn(
+ ProtoOptionRemoved(
+ ProtoOption(
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoOptionRemoved(
+ ProtoOption(
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ )
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOptionAdded(
+ ProtoOption(
+ ProtoIdentifier("some.custom.option.but.not.prior"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ )
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOptionAdded(
+ ProtoOption(
+ ProtoIdentifier("other.option.but.stil.not.prior"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ )
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOptionValueChanged(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.bat")),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ ),
+ diff,
+ )
+ self.assertEqual(5, len(diff))
+
if __name__ == "__main__":
unittest.main()
diff --git a/test/proto_package_test.py b/test/proto_package_test.py
index 0225c19..b6707ba 100644
--- a/test/proto_package_test.py
+++ b/test/proto_package_test.py
@@ -79,8 +79,8 @@ def test_diff_different_package_returns_package_diff(self):
)
def test_diff_package_added(self):
- pp1 = None
- pp2 = ProtoPackage("my.new.package")
+ pp1 = ProtoPackage("my.new.package")
+ pp2 = None
self.assertEqual(
ProtoPackage.diff(pp1, pp2),
[
@@ -89,8 +89,8 @@ def test_diff_package_added(self):
)
def test_diff_package_removed(self):
- pp1 = ProtoPackage("my.old.package")
- pp2 = None
+ pp1 = None
+ pp2 = ProtoPackage("my.old.package")
self.assertEqual(
ProtoPackage.diff(pp1, pp2),
[
From c4191ab31217e30a26c39998da42eac4a0d054cd Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Mon, 13 Feb 2023 21:33:52 -0500
Subject: [PATCH 05/35] Support diffing enum additions & removals (#62)
---
TODO.md | 4 +-
src/BUILD.bazel | 1 +
src/proto_enum.py | 151 ++++++++-
src/proto_file.py | 9 +-
src/proto_import.py | 2 +-
test/proto_enum_test.py | 629 +++++++++++++++++++++++++++++++++++++-
test/proto_import_test.py | 20 +-
7 files changed, 800 insertions(+), 16 deletions(-)
diff --git a/TODO.md b/TODO.md
index 0d937af..f149c01 100644
--- a/TODO.md
+++ b/TODO.md
@@ -59,13 +59,13 @@
- [ ] Diffs
- [x] Normalizing
- [ ] Complete diffs
- - [ ] Proto file-level diffs
+ - [x] Proto file-level diffs
- [x] Syntax changes
- [x] Import changes
- [x] Package changes
- [x] Option changes
- [ ] Enum-level diffs
- - [ ] Additions/removals
+ - [x] Additions/removals
- [ ] Option changes
- [ ] Field changes
- [ ] Value changes
diff --git a/src/BUILD.bazel b/src/BUILD.bazel
index ac1326a..062c592 100644
--- a/src/BUILD.bazel
+++ b/src/BUILD.bazel
@@ -219,6 +219,7 @@ py_library(
srcs = ["proto_file.py"],
visibility = ["//visibility:public"],
deps = [
+ ":proto_enum",
":proto_import",
":proto_node",
":proto_option",
diff --git a/src/proto_enum.py b/src/proto_enum.py
index ecb03fe..8643371 100644
--- a/src/proto_enum.py
+++ b/src/proto_enum.py
@@ -7,7 +7,7 @@
)
from src.proto_identifier import ProtoIdentifier
from src.proto_int import ProtoInt, ProtoIntSign
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
from src.proto_option import ProtoOption
from src.proto_reserved import ProtoReserved
@@ -223,3 +223,152 @@ def serialize(self) -> str:
+ ["}"]
)
return "\n".join(serialize_parts)
+
+ @staticmethod
+ def diff(left: "ProtoEnum", right: "ProtoEnum") -> list["ProtoNodeDiff"]:
+ if left is None and right is not None:
+ return [ProtoEnumAdded(right)]
+ elif left is not None and right is None:
+ return [ProtoEnumRemoved(left)]
+ elif left is None and right is None:
+ return []
+ elif left.name != right.name:
+ return []
+ elif left == right:
+ return []
+ # TODO: process the enum options and values.
+ return []
+
+ @staticmethod
+ def diff_sets(
+ left: list["ProtoEnum"], right: list["ProtoEnum"]
+ ) -> list["ProtoNodeDiff"]:
+ diffs = []
+ left_names = set(o.name.identifier for o in left)
+ right_names = set(o.name.identifier for o in right)
+ for name in left_names - right_names:
+ diffs.append(
+ ProtoEnumAdded(next(i for i in left if i.name.identifier == name))
+ )
+ for name in right_names - left_names:
+ diffs.append(
+ ProtoEnumRemoved(next(i for i in right if i.name.identifier == name))
+ )
+ for name in left_names & right_names:
+ left_option = next(i for i in left if i.name.identifier == name)
+ right_option = next(i for i in right if i.name.identifier == name)
+ diffs.extend(ProtoEnum.diff(left_option, right_option))
+
+ return diffs
+
+
+class ProtoEnumAdded(ProtoNodeDiff):
+ def __init__(self, enum: ProtoEnum):
+ self.enum = enum
+
+ def __eq__(self, other: "ProtoEnumAdded") -> bool:
+ return isinstance(other, ProtoEnumAdded) and self.enum == other.enum
+
+ def __str__(self) -> str:
+ return f""
+
+ def __repr__(self) -> str:
+ return str(self)
+
+
+class ProtoEnumRemoved(ProtoNodeDiff):
+ def __init__(self, enum: ProtoEnum):
+ self.enum = enum
+
+ def __eq__(self, other: "ProtoEnumRemoved") -> bool:
+ return isinstance(other, ProtoEnumRemoved) and self.enum == other.enum
+
+ def __str__(self) -> str:
+ return f""
+
+ def __repr__(self) -> str:
+ return str(self)
+
+
+class ProtoEnumValueAdded(ProtoNodeDiff):
+ def __init__(self, enum: "ProtoEnum", enum_value: "ProtoEnumValue"):
+ self.enum = enum
+ self.enum_value = enum_value
+
+ def __eq__(self, other: "ProtoEnumValueAdded") -> bool:
+ return (
+ isinstance(other, ProtoEnumValueAdded)
+ and self.enum == other.enum
+ and self.enum_value == other.enum_value
+ )
+
+ def __str__(self) -> str:
+ return f""
+
+ def __repr__(self) -> str:
+ return str(self)
+
+
+class ProtoEnumValueRemoved(ProtoNodeDiff):
+ def __init__(self, enum: "ProtoEnum", enum_value: "ProtoEnumValue"):
+ self.enum = enum
+ self.enum_value = enum_value
+
+ def __eq__(self, other: "ProtoEnumValueRemoved") -> bool:
+ return (
+ isinstance(other, ProtoEnumValueRemoved)
+ and self.enum == other.enum
+ and self.enum_value == other.enum_value
+ )
+
+ def __str__(self) -> str:
+ return f""
+
+ def __repr__(self) -> str:
+ return str(self)
+
+
+class ProtoEnumValueNameChanged(ProtoNodeDiff):
+ def __init__(
+ self, enum: ProtoEnum, enum_value: ProtoEnumValue, new_name: ProtoIdentifier
+ ):
+ self.enum = enum
+ self.enum_value = enum_value
+ self.new_name = new_name
+
+ def __eq__(self, other: "ProtoEnumValueNameChanged") -> bool:
+ return (
+ isinstance(other, ProtoEnumValueNameChanged)
+ and self.enum == other.enum
+ and self.enum_value == other.enum_value
+ and self.new_name == other.new_name
+ )
+
+ def __str__(self) -> str:
+ return f""
+
+ def __repr__(self) -> str:
+ return str(self)
+
+
+class ProtoEnumValueValueChanged(ProtoNodeDiff):
+ def __init__(
+ self, enum: ProtoEnum, enum_value: ProtoEnumValue, new_value: ProtoInt
+ ):
+ self.enum = enum
+ self.enum_value = enum_value
+ self.new_value = new_value
+
+ def __eq__(self, other: "ProtoEnumValueNameChanged") -> bool:
+ return (
+ isinstance(other, ProtoEnumValueNameChanged)
+ and self.enum == other.enum
+ and self.enum_value == other.enum_value
+ and self.new_value == other.new_value
+ )
+
+ def __str__(self) -> str:
+ return f""
+
+ def __repr__(self) -> str:
+ return str(self)
diff --git a/src/proto_file.py b/src/proto_file.py
index 01c53e2..2d41cb3 100644
--- a/src/proto_file.py
+++ b/src/proto_file.py
@@ -1,5 +1,6 @@
from typing import Optional
+from src.proto_enum import ProtoEnum
from src.proto_import import ProtoImport
from src.proto_node import ProtoNode, ProtoNodeDiff
from src.proto_option import ProtoOption
@@ -27,6 +28,10 @@ def package(self) -> Optional[ProtoPackage]:
def options(self) -> list[ProtoOption]:
return [node for node in self.nodes if isinstance(node, ProtoOption)]
+ @property
+ def enums(self) -> list[ProtoEnum]:
+ return [node for node in self.nodes if isinstance(node, ProtoEnum)]
+
def serialize(self) -> str:
serialized_parts = [self.syntax.serialize()]
previous_type = self.syntax.__class__
@@ -42,6 +47,8 @@ def serialize(self) -> str:
def diff(self, other: "ProtoFile") -> list[ProtoNodeDiff]:
diffs = []
diffs.extend(ProtoSyntax.diff(self.syntax, other.syntax))
- diffs.extend(ProtoImport.diff(self.imports, other.imports))
+ diffs.extend(ProtoImport.diff_sets(self.imports, other.imports))
diffs.extend(ProtoPackage.diff(self.package, other.package))
+ diffs.extend(ProtoEnum.diff_sets(self.enums, other.enums))
+
return [d for d in diffs if d is not None]
diff --git a/src/proto_import.py b/src/proto_import.py
index dc00a32..f3a5682 100644
--- a/src/proto_import.py
+++ b/src/proto_import.py
@@ -77,7 +77,7 @@ def serialize(self) -> str:
return " ".join(parts)
@staticmethod
- def diff(
+ def diff_sets(
left: list["ProtoImport"], right: list["ProtoImport"]
) -> list["ProtoNodeDiff"]:
diffs = []
diff --git a/test/proto_enum_test.py b/test/proto_enum_test.py
index 8bffd79..76fb369 100644
--- a/test/proto_enum_test.py
+++ b/test/proto_enum_test.py
@@ -4,7 +4,17 @@
from src.proto_bool import ProtoBool
from src.proto_comment import ProtoMultiLineComment, ProtoSingleLineComment
from src.proto_constant import ProtoConstant
-from src.proto_enum import ProtoEnum, ProtoEnumValue, ProtoEnumValueOption
+from src.proto_enum import (
+ ProtoEnum,
+ ProtoEnumAdded,
+ ProtoEnumRemoved,
+ ProtoEnumValue,
+ ProtoEnumValueAdded,
+ ProtoEnumValueNameChanged,
+ ProtoEnumValueOption,
+ ProtoEnumValueRemoved,
+ ProtoEnumValueValueChanged,
+)
from src.proto_identifier import ProtoIdentifier
from src.proto_int import ProtoInt, ProtoIntSign
from src.proto_option import ProtoOption
@@ -295,6 +305,623 @@ def test_enum_normalize_away_comments(self):
],
)
+ def test_diff_same_enum_returns_empty(self):
+ pe1 = ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [],
+ )
+ pe2 = ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [],
+ )
+ self.assertEqual(ProtoEnum.diff(pe1, pe2), [])
+
+ def test_diff_different_enum_name_returns_empty(self):
+ pe1 = ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [],
+ )
+ pe2 = ProtoEnum(
+ ProtoIdentifier("OtherEnum"),
+ [],
+ )
+ self.assertEqual(ProtoEnum.diff(pe1, pe2), [])
+
+ # TODO: handle enum value diffs
+ # def test_diff_different_enum_value_name_returns_enum_diff(self):
+ # pe1 = ProtoEnum(
+ # ProtoIdentifier("MyEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ # )
+ # ],
+ # )
+ # pe2 = ProtoEnum(
+ # ProtoIdentifier("MyEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("ME_KNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ # )
+ # ],
+ # )
+ # self.assertEqual(
+ # ProtoEnum.diff(pe1, pe2),
+ # [
+ # ProtoEnumValueNameChanged(
+ # pe1,
+ # pe1.nodes[0],
+ # ProtoIdentifier("ME_KNOWN"),
+ # )
+ # ],
+ # )
+
+ # def test_diff_different_enum_value_value_returns_enum_diff(self):
+ # pe1 = ProtoEnum(
+ # ProtoIdentifier("MyEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ # )
+ # ],
+ # )
+ # pe2 = ProtoEnum(
+ # ProtoIdentifier("MyEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("ME_UNKNOWN"), ProtoInt(1, ProtoIntSign.POSITIVE)
+ # )
+ # ],
+ # )
+ # self.assertEqual(
+ # ProtoEnum.diff(pe1, pe2),
+ # [
+ # ProtoEnumValueValueChanged(
+ # pe1,
+ # pe1.nodes[0],
+ # ProtoInt(1, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # )
+
+ def test_diff_enum_added(self):
+ pe1 = None
+ pe2 = ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ )
+ ],
+ )
+ self.assertEqual(
+ ProtoEnum.diff(pe1, pe2),
+ [
+ ProtoEnumAdded(
+ ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("ME_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ )
+ ),
+ ],
+ )
+
+ def test_diff_option_removed(self):
+ pe1 = ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ )
+ ],
+ )
+ pe2 = None
+ self.assertEqual(
+ ProtoEnum.diff(pe1, pe2),
+ [
+ ProtoEnumRemoved(
+ ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("ME_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ )
+ ),
+ ],
+ )
+
+ def test_diff_sets_empty_returns_empty(self):
+ set1 = []
+ set2 = []
+ self.assertEqual(ProtoEnum.diff_sets(set1, set2), [])
+
+ def test_diff_sets_no_change(self):
+ set1 = [
+ ProtoEnum(
+ ProtoIdentifier("FooEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("TagEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ]
+ self.assertEqual(ProtoEnum.diff_sets(set1, set1), [])
+
+ def test_diff_sets_all_removed(self):
+ set1 = []
+ set2 = [
+ ProtoEnum(
+ ProtoIdentifier("FooEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("TagEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ]
+ diff = ProtoEnum.diff_sets(set1, set2)
+
+ self.assertIn(
+ ProtoEnumRemoved(
+ ProtoEnum(
+ ProtoIdentifier("FooEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoEnumRemoved(
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoEnumRemoved(
+ ProtoEnum(
+ ProtoIdentifier("TagEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_all_added(self):
+ set1 = [
+ ProtoEnum(
+ ProtoIdentifier("FooEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("TagEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ]
+ set2 = []
+ diff = ProtoEnum.diff_sets(set1, set2)
+
+ self.assertIn(
+ ProtoEnumAdded(
+ ProtoEnum(
+ ProtoIdentifier("FooEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoEnumAdded(
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoEnumAdded(
+ ProtoEnum(
+ ProtoIdentifier("TagEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_mutually_exclusive(self):
+ set1 = [
+ ProtoEnum(
+ ProtoIdentifier("FooEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("TagEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ]
+ set2 = [
+ ProtoEnum(
+ ProtoIdentifier("FooEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("BarEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("TagEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ]
+
+ diff = ProtoEnum.diff_sets(set1, set2)
+
+ self.assertIn(
+ ProtoEnumAdded(
+ ProtoEnum(
+ ProtoIdentifier("FooEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoEnumAdded(
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoEnumAdded(
+ ProtoEnum(
+ ProtoIdentifier("TagEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoEnumRemoved(
+ ProtoEnum(
+ ProtoIdentifier("FooEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoEnumRemoved(
+ ProtoEnum(
+ ProtoIdentifier("BarEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoEnumRemoved(
+ ProtoEnum(
+ ProtoIdentifier("TagEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+
+ self.assertEqual(6, len(diff))
+
+ # TODO: handle enum value diffs
+ # def test_diff_sets_overlap(self):
+ # set1 = [
+ # ProtoEnum(
+ # ProtoIdentifier("FooEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("FE_UNKNOWN"),
+ # ProtoInt(0, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ProtoEnum(
+ # ProtoIdentifier("BarEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("BE_UNKNOWN"),
+ # ProtoInt(0, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ProtoEnum(
+ # ProtoIdentifier("TagEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("TE_UNKNOWN"),
+ # ProtoInt(0, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ]
+ # set2 = [
+ # ProtoEnum(
+ # ProtoIdentifier("FooEnum2"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("FE_UNKNOWN2"),
+ # ProtoInt(0, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ProtoEnum(
+ # ProtoIdentifier("BarEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("BE_UNKNOWN2"),
+ # ProtoInt(1, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ProtoEnum(
+ # ProtoIdentifier("TagEnum2"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("TE_UNKNOWN2"),
+ # ProtoInt(0, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ]
+
+ # diff = ProtoEnum.diff_sets(set1, set2)
+
+ # self.assertIn(
+ # ProtoEnumRemoved(
+ # ProtoEnum(
+ # ProtoIdentifier("FooEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("FE_UNKNOWN"),
+ # ProtoInt(0, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ),
+ # diff,
+ # )
+
+ # self.assertIn(
+ # ProtoEnumRemoved(
+ # ProtoEnum(
+ # ProtoIdentifier("TagEnum"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("TE_UNKNOWN"),
+ # ProtoInt(0, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ),
+ # diff,
+ # )
+ # self.assertIn(
+ # ProtoEnumAdded(
+ # ProtoEnum(
+ # ProtoIdentifier("FooEnum2"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("FE_UNKNOWN2"),
+ # ProtoInt(0, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ),
+ # diff,
+ # )
+ # self.assertIn(
+ # ProtoEnumAdded(
+ # ProtoEnum(
+ # ProtoIdentifier("TagEnum2"),
+ # [
+ # ProtoEnumValue(
+ # ProtoIdentifier("TE_UNKNOWN2"),
+ # ProtoInt(0, ProtoIntSign.POSITIVE),
+ # )
+ # ],
+ # ),
+ # ),
+ # diff,
+ # )
+ # self.assertIn(
+ # ProtoEnumValueRemoved(
+ # ProtoIdentifier("BarEnum"),
+ # ProtoEnumValue(
+ # ProtoIdentifier("BE_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ # ),
+ # ),
+ # diff,
+ # )
+ # self.assertIn(
+ # ProtoEnumValueAdded(
+ # ProtoIdentifier("BarEnum"),
+ # ProtoEnumValue(
+ # ProtoIdentifier("BE_UNKNOWN2"), ProtoInt(1, ProtoIntSign.POSITIVE)
+ # ),
+ # ),
+ # diff,
+ # )
+ # self.assertEqual(6, len(diff))
+
if __name__ == "__main__":
unittest.main()
diff --git a/test/proto_import_test.py b/test/proto_import_test.py
index bf43205..0ea8ffb 100644
--- a/test/proto_import_test.py
+++ b/test/proto_import_test.py
@@ -135,28 +135,28 @@ def test_public_mixed_imports(self):
third_parsed_import.node.serialize(), 'import public "bat.proto";'
)
- def test_diff_same_path_simple(self):
+ def test_diff_sets_same_path_simple(self):
pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
pf2 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
- self.assertEqual(ProtoImport.diff([pf1], [pf2]), [])
+ self.assertEqual(ProtoImport.diff_sets([pf1], [pf2]), [])
- def test_diff_added_path_simple(self):
+ def test_diff_sets_added_path_simple(self):
pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
- self.assertEqual(ProtoImport.diff([pf1], []), [ProtoImportAdded(pf1)])
+ self.assertEqual(ProtoImport.diff_sets([pf1], []), [ProtoImportAdded(pf1)])
- def test_diff_removed_path_simple(self):
+ def test_diff_sets_removed_path_simple(self):
pf2 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
- self.assertEqual(ProtoImport.diff([], [pf2]), [ProtoImportRemoved(pf2)])
+ self.assertEqual(ProtoImport.diff_sets([], [pf2]), [ProtoImportRemoved(pf2)])
- def test_diff_different_path_simple(self):
+ def test_diff_sets_different_path_simple(self):
pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
pf2 = ProtoImport(ProtoStringLiteral("path/to/some/other.proto"))
self.assertEqual(
- ProtoImport.diff([pf1], [pf2]),
+ ProtoImport.diff_sets([pf1], [pf2]),
[ProtoImportAdded(pf1), ProtoImportRemoved(pf2)],
)
- def test_diff_changed_optional_attributes(self):
+ def test_diff_sets_changed_optional_attributes(self):
pf1 = ProtoImport(
ProtoStringLiteral("path/to/some.proto"), weak=False, public=True
)
@@ -164,7 +164,7 @@ def test_diff_changed_optional_attributes(self):
ProtoStringLiteral("path/to/some.proto"), weak=True, public=False
)
self.assertEqual(
- ProtoImport.diff([pf1], [pf2]),
+ ProtoImport.diff_sets([pf1], [pf2]),
[
ProtoImportMadeNonWeak(pf2),
ProtoImportMadePublic(pf2),
From 14765b539ca41d15952c7b4f523eacf282c2dd74 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Mon, 13 Feb 2023 22:42:32 -0500
Subject: [PATCH 06/35] Support enum option, value, & value option diffs (#63)
---
TODO.md | 8 +-
src/proto_enum.py | 104 ++++++++---
src/proto_node.py | 6 +-
src/proto_option.py | 9 -
test/proto_enum_test.py | 390 ++++++++++++++++++++--------------------
5 files changed, 281 insertions(+), 236 deletions(-)
diff --git a/TODO.md b/TODO.md
index f149c01..25185e5 100644
--- a/TODO.md
+++ b/TODO.md
@@ -66,10 +66,10 @@
- [x] Option changes
- [ ] Enum-level diffs
- [x] Additions/removals
- - [ ] Option changes
- - [ ] Field changes
- - [ ] Value changes
- - [ ] Option changes
+ - [x] Option changes
+ - [x] Field changes
+ - [x] Value changes
+ - [x] Option changes
- [ ] Reserveds changes
- [ ] Message-level diffs
- [ ] Additions/removals
diff --git a/src/proto_enum.py b/src/proto_enum.py
index 8643371..2c65c77 100644
--- a/src/proto_enum.py
+++ b/src/proto_enum.py
@@ -62,6 +62,9 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
+ def __hash__(self) -> str:
+ return hash(str(self))
+
def normalize(self) -> "ProtoEnumValue":
return ProtoEnumValue(
self.identifier,
@@ -131,13 +134,72 @@ def serialize(self) -> str:
serialized_parts.append("]")
return " ".join(serialized_parts) + ";"
+ @staticmethod
+ def diff(
+ enum: "ProtoEnum", left: "ProtoEnumValue", right: "ProtoEnumValue"
+ ) -> list["ProtoNodeDiff"]:
+ if left is None and right is not None:
+ return [ProtoEnumValueAdded(right)]
+ elif left is not None and right is None:
+ return [ProtoEnumValueRemoved(left)]
+ elif left is None and right is None:
+ return []
+ elif left.identifier != right.identifier:
+ return []
+ elif left == right:
+ return []
+ diffs = []
+ diffs.extend(ProtoOption.diff_sets(left.options, right.options))
+ diffs.append(ProtoEnumValueValueChanged(enum, right, left.value))
+
+ return diffs
+
+ @staticmethod
+ def diff_sets(
+ enum: "ProtoEnum", left: list["ProtoEnumValue"], right: list["ProtoEnumValue"]
+ ) -> list["ProtoNodeDiff"]:
+ diffs = []
+ left_names = set(o.identifier.identifier for o in left)
+ left_values = set(int(o.value) for o in left)
+ right_names = set(o.identifier.identifier for o in right)
+ right_values = set(int(o.value) for o in right)
+
+ for name in left_names - right_names:
+ # Check to see if this is a renamed field number.
+ left_value = next(i for i in left if i.identifier.identifier == name)
+ if int(left_value.value) in right_values:
+ # This is a renamed field number.
+ right_value = next(
+ i for i in right if int(i.value) == int(left_value.value)
+ )
+ diffs.append(
+ ProtoEnumValueNameChanged(enum, right_value, left_value.identifier)
+ )
+ else:
+ diffs.append(ProtoEnumValueAdded(enum, left_value))
+ for name in right_names - left_names:
+ # Check to see if this is a renamed field number.
+ right_value = next(i for i in right if i.identifier.identifier == name)
+ if int(right_value.value) not in left_values:
+ diffs.append(
+ ProtoEnumValueRemoved(
+ enum, next(i for i in right if i.identifier.identifier == name)
+ )
+ )
+ for name in left_names & right_names:
+ left_enum_value = next(i for i in left if i.identifier.identifier == name)
+ right_enum_value = next(i for i in right if i.identifier.identifier == name)
+ diffs.extend(ProtoEnumValue.diff(enum, left_enum_value, right_enum_value))
+
+ return diffs
+
class ProtoEnum(ProtoNode):
def __init__(self, name: ProtoIdentifier, nodes: list[ProtoNode]):
self.name = name
self.nodes = nodes
- def __eq__(self, other) -> bool:
+ def __eq__(self, other: "ProtoEnum") -> bool:
return self.name == other.name and self.nodes == other.nodes
def __str__(self) -> str:
@@ -216,6 +278,10 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
def options(self) -> list[ProtoOption]:
return [node for node in self.nodes if isinstance(node, ProtoOption)]
+ @property
+ def values(self) -> list[ProtoEnumValue]:
+ return [node for node in self.nodes if isinstance(node, ProtoEnumValue)]
+
def serialize(self) -> str:
serialize_parts = (
[f"enum {self.name.serialize()} {{"]
@@ -236,8 +302,10 @@ def diff(left: "ProtoEnum", right: "ProtoEnum") -> list["ProtoNodeDiff"]:
return []
elif left == right:
return []
- # TODO: process the enum options and values.
- return []
+ diffs = []
+ diffs.extend(ProtoOption.diff_sets(left.options, right.options))
+ diffs.extend(ProtoEnumValue.diff_sets(left, left.values, right.values))
+ return diffs
@staticmethod
def diff_sets(
@@ -255,9 +323,9 @@ def diff_sets(
ProtoEnumRemoved(next(i for i in right if i.name.identifier == name))
)
for name in left_names & right_names:
- left_option = next(i for i in left if i.name.identifier == name)
- right_option = next(i for i in right if i.name.identifier == name)
- diffs.extend(ProtoEnum.diff(left_option, right_option))
+ left_enum = next(i for i in left if i.name.identifier == name)
+ right_enum = next(i for i in right if i.name.identifier == name)
+ diffs.extend(ProtoEnum.diff(left_enum, right_enum))
return diffs
@@ -272,9 +340,6 @@ def __eq__(self, other: "ProtoEnumAdded") -> bool:
def __str__(self) -> str:
return f""
- def __repr__(self) -> str:
- return str(self)
-
class ProtoEnumRemoved(ProtoNodeDiff):
def __init__(self, enum: ProtoEnum):
@@ -286,9 +351,6 @@ def __eq__(self, other: "ProtoEnumRemoved") -> bool:
def __str__(self) -> str:
return f""
- def __repr__(self) -> str:
- return str(self)
-
class ProtoEnumValueAdded(ProtoNodeDiff):
def __init__(self, enum: "ProtoEnum", enum_value: "ProtoEnumValue"):
@@ -305,9 +367,6 @@ def __eq__(self, other: "ProtoEnumValueAdded") -> bool:
def __str__(self) -> str:
return f""
- def __repr__(self) -> str:
- return str(self)
-
class ProtoEnumValueRemoved(ProtoNodeDiff):
def __init__(self, enum: "ProtoEnum", enum_value: "ProtoEnumValue"):
@@ -324,9 +383,6 @@ def __eq__(self, other: "ProtoEnumValueRemoved") -> bool:
def __str__(self) -> str:
return f""
- def __repr__(self) -> str:
- return str(self)
-
class ProtoEnumValueNameChanged(ProtoNodeDiff):
def __init__(
@@ -347,9 +403,6 @@ def __eq__(self, other: "ProtoEnumValueNameChanged") -> bool:
def __str__(self) -> str:
return f""
- def __repr__(self) -> str:
- return str(self)
-
class ProtoEnumValueValueChanged(ProtoNodeDiff):
def __init__(
@@ -359,16 +412,13 @@ def __init__(
self.enum_value = enum_value
self.new_value = new_value
- def __eq__(self, other: "ProtoEnumValueNameChanged") -> bool:
+ def __eq__(self, other: "ProtoEnumValueValueChanged") -> bool:
return (
- isinstance(other, ProtoEnumValueNameChanged)
+ isinstance(other, ProtoEnumValueValueChanged)
and self.enum == other.enum
and self.enum_value == other.enum_value
and self.new_value == other.new_value
)
def __str__(self) -> str:
- return f""
-
- def __repr__(self) -> str:
- return str(self)
+ return f""
diff --git a/src/proto_node.py b/src/proto_node.py
index 05310eb..162fe74 100644
--- a/src/proto_node.py
+++ b/src/proto_node.py
@@ -29,4 +29,8 @@ def __repr__(self) -> str:
class ProtoNodeDiff(abc.ABC):
- pass
+ def __repr__(self) -> str:
+ return str(self)
+
+ def __hash__(self) -> str:
+ return hash(str(self))
diff --git a/src/proto_option.py b/src/proto_option.py
index e86e360..58c02cf 100644
--- a/src/proto_option.py
+++ b/src/proto_option.py
@@ -149,9 +149,6 @@ def __eq__(self, other: "ProtoOptionValueChanged") -> bool:
def __str__(self) -> str:
return f""
- def __repr__(self) -> str:
- return str(self)
-
class ProtoOptionAdded(ProtoNodeDiff):
def __init__(self, left: str):
@@ -163,9 +160,6 @@ def __eq__(self, other: "ProtoOptionAdded") -> bool:
def __str__(self) -> str:
return f""
- def __repr__(self) -> str:
- return str(self)
-
class ProtoOptionRemoved(ProtoNodeDiff):
def __init__(self, right: str):
@@ -176,6 +170,3 @@ def __eq__(self, other: "ProtoOptionRemoved") -> bool:
def __str__(self) -> str:
return f""
-
- def __repr__(self) -> str:
- return str(self)
diff --git a/test/proto_enum_test.py b/test/proto_enum_test.py
index 76fb369..3857d32 100644
--- a/test/proto_enum_test.py
+++ b/test/proto_enum_test.py
@@ -327,62 +327,63 @@ def test_diff_different_enum_name_returns_empty(self):
)
self.assertEqual(ProtoEnum.diff(pe1, pe2), [])
- # TODO: handle enum value diffs
- # def test_diff_different_enum_value_name_returns_enum_diff(self):
- # pe1 = ProtoEnum(
- # ProtoIdentifier("MyEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
- # )
- # ],
- # )
- # pe2 = ProtoEnum(
- # ProtoIdentifier("MyEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("ME_KNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
- # )
- # ],
- # )
- # self.assertEqual(
- # ProtoEnum.diff(pe1, pe2),
- # [
- # ProtoEnumValueNameChanged(
- # pe1,
- # pe1.nodes[0],
- # ProtoIdentifier("ME_KNOWN"),
- # )
- # ],
- # )
-
- # def test_diff_different_enum_value_value_returns_enum_diff(self):
- # pe1 = ProtoEnum(
- # ProtoIdentifier("MyEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
- # )
- # ],
- # )
- # pe2 = ProtoEnum(
- # ProtoIdentifier("MyEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("ME_UNKNOWN"), ProtoInt(1, ProtoIntSign.POSITIVE)
- # )
- # ],
- # )
- # self.assertEqual(
- # ProtoEnum.diff(pe1, pe2),
- # [
- # ProtoEnumValueValueChanged(
- # pe1,
- # pe1.nodes[0],
- # ProtoInt(1, ProtoIntSign.POSITIVE),
- # )
- # ],
- # )
+ def test_diff_different_enum_value_name_returns_enum_diff(self):
+ pe1 = ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ )
+ ],
+ )
+ pe2 = ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("ME_KNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ )
+ ],
+ )
+ self.assertEqual(
+ ProtoEnum.diff(pe1, pe2),
+ [
+ ProtoEnumValueNameChanged(
+ pe1,
+ pe2.nodes[0],
+ ProtoIdentifier("ME_UNKNOWN"),
+ )
+ ],
+ )
+
+ def test_diff_different_enum_value_value_returns_enum_diff(self):
+ pe1 = ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ )
+ ],
+ )
+ pe2 = ProtoEnum(
+ ProtoIdentifier("MyEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("ME_UNKNOWN"), ProtoInt(1, ProtoIntSign.POSITIVE)
+ )
+ ],
+ )
+
+ diff = ProtoEnum.diff(pe1, pe2)
+
+ self.assertIn(
+ ProtoEnumValueValueChanged(
+ pe1,
+ pe2.values[0],
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ ),
+ diff,
+ )
+ self.assertEqual(1, len(diff))
def test_diff_enum_added(self):
pe1 = None
@@ -782,145 +783,144 @@ def test_diff_sets_mutually_exclusive(self):
self.assertEqual(6, len(diff))
- # TODO: handle enum value diffs
- # def test_diff_sets_overlap(self):
- # set1 = [
- # ProtoEnum(
- # ProtoIdentifier("FooEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("FE_UNKNOWN"),
- # ProtoInt(0, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ProtoEnum(
- # ProtoIdentifier("BarEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("BE_UNKNOWN"),
- # ProtoInt(0, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ProtoEnum(
- # ProtoIdentifier("TagEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("TE_UNKNOWN"),
- # ProtoInt(0, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ]
- # set2 = [
- # ProtoEnum(
- # ProtoIdentifier("FooEnum2"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("FE_UNKNOWN2"),
- # ProtoInt(0, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ProtoEnum(
- # ProtoIdentifier("BarEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("BE_UNKNOWN2"),
- # ProtoInt(1, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ProtoEnum(
- # ProtoIdentifier("TagEnum2"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("TE_UNKNOWN2"),
- # ProtoInt(0, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ]
-
- # diff = ProtoEnum.diff_sets(set1, set2)
-
- # self.assertIn(
- # ProtoEnumRemoved(
- # ProtoEnum(
- # ProtoIdentifier("FooEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("FE_UNKNOWN"),
- # ProtoInt(0, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ),
- # diff,
- # )
-
- # self.assertIn(
- # ProtoEnumRemoved(
- # ProtoEnum(
- # ProtoIdentifier("TagEnum"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("TE_UNKNOWN"),
- # ProtoInt(0, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ),
- # diff,
- # )
- # self.assertIn(
- # ProtoEnumAdded(
- # ProtoEnum(
- # ProtoIdentifier("FooEnum2"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("FE_UNKNOWN2"),
- # ProtoInt(0, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ),
- # diff,
- # )
- # self.assertIn(
- # ProtoEnumAdded(
- # ProtoEnum(
- # ProtoIdentifier("TagEnum2"),
- # [
- # ProtoEnumValue(
- # ProtoIdentifier("TE_UNKNOWN2"),
- # ProtoInt(0, ProtoIntSign.POSITIVE),
- # )
- # ],
- # ),
- # ),
- # diff,
- # )
- # self.assertIn(
- # ProtoEnumValueRemoved(
- # ProtoIdentifier("BarEnum"),
- # ProtoEnumValue(
- # ProtoIdentifier("BE_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
- # ),
- # ),
- # diff,
- # )
- # self.assertIn(
- # ProtoEnumValueAdded(
- # ProtoIdentifier("BarEnum"),
- # ProtoEnumValue(
- # ProtoIdentifier("BE_UNKNOWN2"), ProtoInt(1, ProtoIntSign.POSITIVE)
- # ),
- # ),
- # diff,
- # )
- # self.assertEqual(6, len(diff))
+ def test_diff_sets_overlap(self):
+ set1 = [
+ ProtoEnum(
+ ProtoIdentifier("FooEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("TagEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ]
+ set2 = [
+ ProtoEnum(
+ ProtoIdentifier("FooEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnum(
+ ProtoIdentifier("TagEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ]
+
+ diff = ProtoEnum.diff_sets(set1, set2)
+
+ self.assertIn(
+ ProtoEnumRemoved(
+ ProtoEnum(
+ ProtoIdentifier("FooEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoEnumRemoved(
+ ProtoEnum(
+ ProtoIdentifier("TagEnum2"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoEnumAdded(
+ ProtoEnum(
+ ProtoIdentifier("FooEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoEnumAdded(
+ ProtoEnum(
+ ProtoIdentifier("TagEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoEnumValueNameChanged(
+ ProtoEnum(
+ ProtoIdentifier("BarEnum"),
+ [
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
+ )
+ ],
+ ),
+ ProtoEnumValue(
+ ProtoIdentifier("BE_UNKNOWN2"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ ),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ),
+ diff,
+ )
+ self.assertEqual(5, len(diff))
if __name__ == "__main__":
From 5aa9cd790bda388d3838a14aca3247c57768556c Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Fri, 17 Feb 2023 19:22:26 -0500
Subject: [PATCH 07/35] Add support for emitting diffs for added & removed
messages (#64)
---
TODO.md | 14 +++-
src/BUILD.bazel | 1 +
src/proto_enum.py | 2 +
src/proto_file.py | 6 ++
src/proto_message.py | 63 ++++++++++++++-
test/proto_enum_test.py | 4 +-
test/proto_message_test.py | 159 ++++++++++++++++++++++++++++++++++++-
7 files changed, 241 insertions(+), 8 deletions(-)
diff --git a/TODO.md b/TODO.md
index 25185e5..7922d51 100644
--- a/TODO.md
+++ b/TODO.md
@@ -72,8 +72,8 @@
- [x] Option changes
- [ ] Reserveds changes
- [ ] Message-level diffs
- - [ ] Additions/removals
- - [ ] Option changes
+ - [x] Additions/removals
+ - [x] Option changes
- [ ] Field changes
- [ ] Reserved changes
- [ ] Nested enum changes
@@ -85,3 +85,13 @@
- [ ] Additions/removals
- [ ] Option changes
- [ ] Backwards-compatibility check
+ - [ ] Scoping of diffs under containing objects
+ - [ ] Enum options under enums
+ - [ ] Enum value changes under enums
+ - [ ] Enum value option changes under enum values
+ - [ ] Enum reserved changes under enums
+ - [ ] Message option changes under messages
+ - [ ] Message field changes under messages
+ - [ ] Message reserved changes under messages
+ - [ ] Message nested enum changes under messages
+ - [ ] Message nested message changes under messages
diff --git a/src/BUILD.bazel b/src/BUILD.bazel
index 062c592..3774c4c 100644
--- a/src/BUILD.bazel
+++ b/src/BUILD.bazel
@@ -221,6 +221,7 @@ py_library(
deps = [
":proto_enum",
":proto_import",
+ ":proto_message",
":proto_node",
":proto_option",
":proto_package",
diff --git a/src/proto_enum.py b/src/proto_enum.py
index 2c65c77..47b658f 100644
--- a/src/proto_enum.py
+++ b/src/proto_enum.py
@@ -149,6 +149,7 @@ def diff(
elif left == right:
return []
diffs = []
+ # TODO: scope these diffs under ProtoEnumValue
diffs.extend(ProtoOption.diff_sets(left.options, right.options))
diffs.append(ProtoEnumValueValueChanged(enum, right, left.value))
@@ -303,6 +304,7 @@ def diff(left: "ProtoEnum", right: "ProtoEnum") -> list["ProtoNodeDiff"]:
elif left == right:
return []
diffs = []
+ # TODO: scope these diffs under ProtoEnum
diffs.extend(ProtoOption.diff_sets(left.options, right.options))
diffs.extend(ProtoEnumValue.diff_sets(left, left.values, right.values))
return diffs
diff --git a/src/proto_file.py b/src/proto_file.py
index 2d41cb3..4bfedb9 100644
--- a/src/proto_file.py
+++ b/src/proto_file.py
@@ -2,6 +2,7 @@
from src.proto_enum import ProtoEnum
from src.proto_import import ProtoImport
+from src.proto_message import ProtoMessage
from src.proto_node import ProtoNode, ProtoNodeDiff
from src.proto_option import ProtoOption
from src.proto_package import ProtoPackage
@@ -32,6 +33,10 @@ def options(self) -> list[ProtoOption]:
def enums(self) -> list[ProtoEnum]:
return [node for node in self.nodes if isinstance(node, ProtoEnum)]
+ @property
+ def messages(self) -> list[ProtoMessage]:
+ return [node for node in self.nodes if isinstance(node, ProtoMessage)]
+
def serialize(self) -> str:
serialized_parts = [self.syntax.serialize()]
previous_type = self.syntax.__class__
@@ -50,5 +55,6 @@ def diff(self, other: "ProtoFile") -> list[ProtoNodeDiff]:
diffs.extend(ProtoImport.diff_sets(self.imports, other.imports))
diffs.extend(ProtoPackage.diff(self.package, other.package))
diffs.extend(ProtoEnum.diff_sets(self.enums, other.enums))
+ diffs.extend(ProtoMessage.diff_sets(self.message, other.messages))
return [d for d in diffs if d is not None]
diff --git a/src/proto_message.py b/src/proto_message.py
index 3bb2b81..b2fb80c 100644
--- a/src/proto_message.py
+++ b/src/proto_message.py
@@ -20,7 +20,7 @@
ProtoMessageFieldOption,
ProtoMessageFieldTypesEnum,
)
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
from src.proto_option import ProtoOption
from src.proto_reserved import ProtoReserved
@@ -461,3 +461,64 @@ def serialize(self) -> str:
+ ["}"]
)
return "\n".join(serialize_parts)
+
+ @staticmethod
+ def diff(left: "ProtoMessage", right: "ProtoMessage") -> list["ProtoNodeDiff"]:
+ if left is None and right is not None:
+ return [ProtoMessageAdded(right)]
+ elif left is not None and right is None:
+ return [ProtoMessageRemoved(left)]
+ elif left is None and right is None:
+ return []
+ elif left.name != right.name:
+ return []
+ elif left == right:
+ return []
+ diffs = []
+ diffs.extend(ProtoOption.diff_sets(left.options, right.options))
+ # diffs.extend(ProtoMessageValue.diff_sets(left, left.values, right.values))
+ return diffs
+
+ @staticmethod
+ def diff_sets(
+ left: list["ProtoMessage"], right: list["ProtoMessage"]
+ ) -> list["ProtoNodeDiff"]:
+ diffs = []
+ left_names = set(o.name.identifier for o in left)
+ right_names = set(o.name.identifier for o in right)
+ for name in left_names - right_names:
+ diffs.append(
+ ProtoMessageAdded(next(i for i in left if i.name.identifier == name))
+ )
+ for name in right_names - left_names:
+ diffs.append(
+ ProtoMessageRemoved(next(i for i in right if i.name.identifier == name))
+ )
+ for name in left_names & right_names:
+ left_enum = next(i for i in left if i.name.identifier == name)
+ right_enum = next(i for i in right if i.name.identifier == name)
+ diffs.extend(ProtoMessage.diff(left_enum, right_enum))
+
+ return diffs
+
+
+class ProtoMessageAdded(ProtoNodeDiff):
+ def __init__(self, message: ProtoMessage):
+ self.message = message
+
+ def __eq__(self, other: "ProtoMessageAdded") -> bool:
+ return isinstance(other, ProtoMessageAdded) and self.message == other.message
+
+ def __str__(self) -> str:
+ return f""
+
+
+class ProtoMessageRemoved(ProtoNodeDiff):
+ def __init__(self, message: ProtoMessage):
+ self.message = message
+
+ def __eq__(self, other: "ProtoMessageRemoved") -> bool:
+ return isinstance(other, ProtoMessageRemoved) and self.message == other.message
+
+ def __str__(self) -> str:
+ return f""
diff --git a/test/proto_enum_test.py b/test/proto_enum_test.py
index 3857d32..4687151 100644
--- a/test/proto_enum_test.py
+++ b/test/proto_enum_test.py
@@ -9,10 +9,8 @@
ProtoEnumAdded,
ProtoEnumRemoved,
ProtoEnumValue,
- ProtoEnumValueAdded,
ProtoEnumValueNameChanged,
ProtoEnumValueOption,
- ProtoEnumValueRemoved,
ProtoEnumValueValueChanged,
)
from src.proto_identifier import ProtoIdentifier
@@ -412,7 +410,7 @@ def test_diff_enum_added(self):
],
)
- def test_diff_option_removed(self):
+ def test_diff_enum_removed(self):
pe1 = ProtoEnum(
ProtoIdentifier("MyEnum"),
[
diff --git a/test/proto_message_test.py b/test/proto_message_test.py
index 2dc0878..19195a9 100644
--- a/test/proto_message_test.py
+++ b/test/proto_message_test.py
@@ -18,6 +18,8 @@
ProtoMapKeyTypesEnum,
ProtoMapValueTypesEnum,
ProtoMessage,
+ ProtoMessageAdded,
+ ProtoMessageRemoved,
ProtoOneOf,
)
from src.proto_message_field import (
@@ -70,7 +72,7 @@ def test_message_all_features(self):
ProtoIdentifier("(foo.bar).baz"),
ProtoConstant(ProtoStringLiteral("bat")),
),
- ProtoEnum(
+ ProtoMessage(
ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
@@ -293,7 +295,7 @@ def test_message_nested_enum(self):
ProtoMessage(
ProtoIdentifier("FooMessage"),
[
- ProtoEnum(
+ ProtoMessage(
ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
@@ -762,6 +764,159 @@ def test_message_normalizes_away_comments(self):
],
)
+ def test_diff_same_message_returns_empty(self):
+ pm1 = ProtoMessage(
+ ProtoIdentifier("MyMessage"),
+ [],
+ )
+ pm2 = ProtoMessage(
+ ProtoIdentifier("MyMessage"),
+ [],
+ )
+ self.assertEqual(ProtoMessage.diff(pm1, pm2), [])
+
+ def test_diff_different_message_name_returns_empty(self):
+ pm1 = ProtoMessage(
+ ProtoIdentifier("MyMessage"),
+ [],
+ )
+ pm2 = ProtoMessage(
+ ProtoIdentifier("OtherMessage"),
+ [],
+ )
+ self.assertEqual(ProtoMessage.diff(pm1, pm2), [])
+
+ def test_diff_enum_added(self):
+ pm1 = None
+ pm2 = ProtoMessage(ProtoIdentifier("MyMessage"), [])
+ self.assertEqual(
+ ProtoMessage.diff(pm1, pm2),
+ [
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("MyMessage"), [])),
+ ],
+ )
+
+ def test_diff_message_removed(self):
+ pm1 = ProtoMessage(ProtoIdentifier("MyMessage"), [])
+ pm2 = None
+ self.assertEqual(
+ ProtoMessage.diff(pm1, pm2),
+ [
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("MyMessage"), [])),
+ ],
+ )
+
+ def test_diff_sets_empty_returns_empty(self):
+ set1 = []
+ set2 = []
+ self.assertEqual(ProtoMessage.diff_sets(set1, set2), [])
+
+ def test_diff_sets_no_change_returns_empty(self):
+ set1 = [
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ]
+ self.assertEqual(ProtoMessage.diff_sets(set1, set1), [])
+
+ def test_diff_sets_all_removed(self):
+ set1 = []
+ set2 = [
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ]
+ diff = ProtoMessage.diff_sets(set1, set2)
+ self.assertIn(
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BarMessage"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage"), [])), diff
+ )
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_all_added(self):
+ set1 = [
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ]
+ set2 = []
+
+ diff = ProtoMessage.diff_sets(set1, set2)
+ self.assertIn(
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BarMessage"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage"), [])), diff
+ )
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_mutually_exclusive(self):
+ set1 = [
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ]
+ set2 = [
+ ProtoMessage(ProtoIdentifier("FooMessage2"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage2"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage2"), []),
+ ]
+ diff = ProtoMessage.diff_sets(set1, set2)
+ self.assertIn(
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BarMessage"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage2"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BarMessage2"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage2"), [])), diff
+ )
+ self.assertEqual(6, len(diff))
+
+ def test_diff_sets_overlap(self):
+
+ set1 = [
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ]
+ set2 = [
+ ProtoMessage(ProtoIdentifier("FooMessage2"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage2"), []),
+ ]
+ diff = ProtoMessage.diff_sets(set1, set2)
+ self.assertIn(
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage2"), [])), diff
+ )
+ self.assertIn(
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage2"), [])), diff
+ )
+ self.assertEqual(4, len(diff))
+
if __name__ == "__main__":
unittest.main()
From 6f7e85eae660ce353b363b40caf6ab357e0c4557 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Fri, 17 Feb 2023 19:29:14 -0500
Subject: [PATCH 08/35] Add todo for perf & iterators (#65)
---
TODO.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/TODO.md b/TODO.md
index 7922d51..ca4a7e7 100644
--- a/TODO.md
+++ b/TODO.md
@@ -95,3 +95,7 @@
- [ ] Message reserved changes under messages
- [ ] Message nested enum changes under messages
- [ ] Message nested message changes under messages
+- [ ] (Perf) use iterators
+ - [ ] In parsing
+ - [ ] In properties
+- [ ] Remove Proto* and proto_ from everything
From b2aa495dcd83a224248f1ee1597c240b61805ee3 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Fri, 17 Feb 2023 20:00:36 -0500
Subject: [PATCH 09/35] Add compatibility checker binary, and shell test (#67)
---
src/BUILD.bazel | 19 +++++++++++
src/compatibility_checker.py | 40 +++++++++++++++++++++++
src/proto_file.py | 7 ++--
test/BUILD.bazel | 9 +++++
test/compatibility_checker_binary_test.sh | 4 +++
test/resources/single_message.proto | 3 ++
6 files changed, 80 insertions(+), 2 deletions(-)
create mode 100644 src/compatibility_checker.py
create mode 100755 test/compatibility_checker_binary_test.sh
create mode 100644 test/resources/single_message.proto
diff --git a/src/BUILD.bazel b/src/BUILD.bazel
index 3774c4c..892c9a3 100644
--- a/src/BUILD.bazel
+++ b/src/BUILD.bazel
@@ -254,3 +254,22 @@ py_binary(
visibility = ["//visibility:public"],
deps = [":parser"],
)
+
+py_library(
+ name = "compatibility_checker",
+ srcs = ["compatibility_checker.py"],
+ visibility = ["//visibility:public"],
+ deps = [
+ ":parser",
+ ":proto_file",
+ ":proto_node",
+ ],
+)
+
+py_binary(
+ name = "compatibility_checker_binary",
+ srcs = ["compatibility_checker.py"],
+ main = "compatibility_checker.py",
+ visibility = ["//visibility:public"],
+ deps = [":compatibility_checker"],
+)
diff --git a/src/compatibility_checker.py b/src/compatibility_checker.py
new file mode 100644
index 0000000..8971f72
--- /dev/null
+++ b/src/compatibility_checker.py
@@ -0,0 +1,40 @@
+import sys
+from dataclasses import dataclass
+from typing import Type
+
+from src.parser import Parser
+from src.proto_file import ProtoFile
+from src.proto_message import ProtoMessageAdded
+from src.proto_node import ProtoNodeDiff
+
+
+@dataclass
+class CompatibilityChecker:
+ allowed_diff_types: list[Type[ProtoNodeDiff]]
+
+ def check_compatibility(self, left: ProtoFile, right: ProtoFile):
+ for diff in left.diff(right):
+ if diff.__class__ in self.allowed_diff_types:
+ continue
+ yield diff
+
+
+def main() -> int:
+ with open(sys.argv[1], "r") as proto_file:
+ left = Parser.loads(proto_file.read())
+
+ with open(sys.argv[2], "r") as proto_file:
+ right = Parser.loads(proto_file.read())
+
+ violations = list(
+ CompatibilityChecker([ProtoMessageAdded]).check_compatibility(left, right)
+ )
+ if violations:
+ print(f"Violations: {violations}")
+ return 1
+
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/src/proto_file.py b/src/proto_file.py
index 4bfedb9..f70a210 100644
--- a/src/proto_file.py
+++ b/src/proto_file.py
@@ -23,7 +23,10 @@ def imports(self) -> list[ProtoImport]:
@property
def package(self) -> Optional[ProtoPackage]:
- return next(node for node in self.nodes if isinstance(node, ProtoPackage))
+ try:
+ return next(node for node in self.nodes if isinstance(node, ProtoPackage))
+ except StopIteration:
+ return None
@property
def options(self) -> list[ProtoOption]:
@@ -55,6 +58,6 @@ def diff(self, other: "ProtoFile") -> list[ProtoNodeDiff]:
diffs.extend(ProtoImport.diff_sets(self.imports, other.imports))
diffs.extend(ProtoPackage.diff(self.package, other.package))
diffs.extend(ProtoEnum.diff_sets(self.enums, other.enums))
- diffs.extend(ProtoMessage.diff_sets(self.message, other.messages))
+ diffs.extend(ProtoMessage.diff_sets(self.messages, other.messages))
return [d for d in diffs if d is not None]
diff --git a/test/BUILD.bazel b/test/BUILD.bazel
index b538aae..a2954d7 100644
--- a/test/BUILD.bazel
+++ b/test/BUILD.bazel
@@ -231,3 +231,12 @@ sh_test(
"@com_google_protobuf//:all_proto",
],
)
+
+sh_test(
+ name = "compatibility_checker_binary_test",
+ srcs = ["compatibility_checker_binary_test.sh"],
+ data = [
+ "//src:compatibility_checker_binary",
+ "//test/resources:all_protos",
+ ],
+)
diff --git a/test/compatibility_checker_binary_test.sh b/test/compatibility_checker_binary_test.sh
new file mode 100755
index 0000000..0f01063
--- /dev/null
+++ b/test/compatibility_checker_binary_test.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+set -euxo pipefail
+
+./src/compatibility_checker_binary ./test/resources/single_message.proto ./test/resources/empty.proto
diff --git a/test/resources/single_message.proto b/test/resources/single_message.proto
new file mode 100644
index 0000000..4b3d2f1
--- /dev/null
+++ b/test/resources/single_message.proto
@@ -0,0 +1,3 @@
+syntax = "proto3";
+
+message MyMessage {}
From cea35c7bcf11987bd9a2e45ceff2e5cfefaf2057 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sat, 18 Feb 2023 03:14:06 -0500
Subject: [PATCH 10/35] Fix all the mypy typing errors, and turn on mypy
precommit (#68)
---
.pre-commit-config.yaml | 8 +-
src/parser.py | 28 ++++---
src/proto_bool.py | 11 ++-
src/proto_comment.py | 26 +++++--
src/proto_constant.py | 61 ++++++++-------
src/proto_enum.py | 149 ++++++++++++++++++------------------
src/proto_extend.py | 7 +-
src/proto_extensions.py | 3 +-
src/proto_file.py | 8 +-
src/proto_float.py | 13 +++-
src/proto_identifier.py | 46 +++++++----
src/proto_import.py | 15 ++--
src/proto_int.py | 13 +++-
src/proto_message.py | 115 +++++++++++++++++-----------
src/proto_message_field.py | 64 ++++++++++------
src/proto_node.py | 2 +-
src/proto_option.py | 83 ++++++++++++--------
src/proto_package.py | 28 ++++---
src/proto_range.py | 11 ++-
src/proto_reserved.py | 20 +++--
src/proto_service.py | 8 +-
src/proto_string_literal.py | 9 ++-
src/proto_syntax.py | 21 +++--
test/proto_message_test.py | 4 +-
24 files changed, 455 insertions(+), 298 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index ab36cc1..d256485 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -23,7 +23,7 @@ repos:
rev: "12f5442f51377b10b26651ad745206bbe1500ad6"
hooks:
- id: bazel-buildifier
- # - repo: https://github.com/pre-commit/mirrors-mypy
- # rev: v0.991
- # hooks:
- # - id: mypy
+ - repo: https://github.com/pre-commit/mirrors-mypy
+ rev: v0.991
+ hooks:
+ - id: mypy
diff --git a/src/parser.py b/src/parser.py
index 043097a..75b9de9 100644
--- a/src/parser.py
+++ b/src/parser.py
@@ -1,12 +1,17 @@
import sys
+from typing import Sequence
-from src.proto_comment import ProtoMultiLineComment, ProtoSingleLineComment
+from src.proto_comment import (
+ ProtoComment,
+ ProtoMultiLineComment,
+ ProtoSingleLineComment,
+)
from src.proto_enum import ProtoEnum
from src.proto_extend import ProtoExtend
from src.proto_file import ProtoFile
from src.proto_import import ProtoImport
from src.proto_message import ProtoMessage
-from src.proto_node import ParsedProtoNode
+from src.proto_node import ParsedProtoNode, ProtoNode
from src.proto_option import ProtoOption
from src.proto_package import ProtoPackage
from src.proto_service import ProtoService
@@ -20,7 +25,7 @@ class ParseError(ValueError):
class Parser:
@staticmethod
def parse_partial_content(partial_proto_content: str) -> ParsedProtoNode:
- node_types = [
+ node_types: list[type[ProtoNode]] = [
ProtoImport,
ProtoMessage,
ProtoPackage,
@@ -30,7 +35,7 @@ def parse_partial_content(partial_proto_content: str) -> ParsedProtoNode:
ProtoService,
ProtoSingleLineComment,
ProtoMultiLineComment,
- ] # type: list[type[ProtoImport] | type[ProtoMessage] | type[ProtoPackage] | type[ProtoOption] | type[ProtoEnum] | type[ProtoExtend]]
+ ]
for node_type in node_types:
try:
match_result = node_type.match(partial_proto_content)
@@ -45,7 +50,7 @@ def parse_partial_content(partial_proto_content: str) -> ParsedProtoNode:
@staticmethod
def parse_syntax_and_preceding_comments(
proto_content: str,
- ) -> tuple[ProtoSyntax, list[ProtoSingleLineComment | ProtoMultiLineComment], str]:
+ ) -> tuple[ProtoSyntax, Sequence[ProtoComment], str]:
# First, parse any preceding comments.
parsed_tree = []
while True:
@@ -63,13 +68,13 @@ def parse_syntax_and_preceding_comments(
# Next, parse syntax.
try:
- match_result = ProtoSyntax.match(proto_content.strip())
+ syntax_match = ProtoSyntax.match(proto_content.strip())
except (ValueError, IndexError, TypeError):
raise ParseError(f"Proto doesn't have parseable syntax:\n{proto_content}")
- if match_result is None:
+ if syntax_match is None:
raise ParseError(f"Proto doesn't have parseable syntax:\n{proto_content}")
- syntax = match_result.node
- proto_content = match_result.remaining_source.strip()
+ syntax = syntax_match.node
+ proto_content = syntax_match.remaining_source.strip()
return syntax, parsed_tree, proto_content
@@ -78,16 +83,17 @@ def loads(proto_content: str) -> ProtoFile:
syntax, parsed_tree, proto_content = Parser.parse_syntax_and_preceding_comments(
proto_content
)
+ new_tree: list[ProtoNode] = list(parsed_tree)
while proto_content:
# Remove empty statements.
if proto_content.startswith(";"):
proto_content = proto_content[1:].strip()
continue
match_result = Parser.parse_partial_content(proto_content)
- parsed_tree.append(match_result.node)
+ new_tree.append(match_result.node)
proto_content = match_result.remaining_source.strip()
- return ProtoFile(syntax, parsed_tree)
+ return ProtoFile(syntax, new_tree)
if __name__ == "__main__":
diff --git a/src/proto_bool.py b/src/proto_bool.py
index ef8867a..4704aa1 100644
--- a/src/proto_bool.py
+++ b/src/proto_bool.py
@@ -4,6 +4,11 @@
from src.proto_node import ParsedProtoNode, ProtoNode
+class ParsedProtoBoolNode(ParsedProtoNode):
+ node: "ProtoBool"
+ remaining_source: str
+
+
class ProtoBool(ProtoNode):
def __init__(self, value: bool):
self.value = value
@@ -24,15 +29,15 @@ def normalize(self) -> "ProtoBool":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoBoolNode"]:
if proto_source.startswith("true") and (
len(proto_source) == 4 or proto_source[4] not in ProtoFullIdentifier.ALL
):
- return ParsedProtoNode(ProtoBool(True), proto_source[4:].strip())
+ return ParsedProtoBoolNode(ProtoBool(True), proto_source[4:].strip())
elif proto_source.startswith("false") and (
len(proto_source) == 5 or proto_source[5] not in ProtoFullIdentifier.ALL
):
- return ParsedProtoNode(ProtoBool(False), proto_source[5:].strip())
+ return ParsedProtoBoolNode(ProtoBool(False), proto_source[5:].strip())
return None
def serialize(self) -> str:
diff --git a/src/proto_comment.py b/src/proto_comment.py
index 989803c..8d726ed 100644
--- a/src/proto_comment.py
+++ b/src/proto_comment.py
@@ -1,10 +1,14 @@
import abc
from typing import Optional
-from src.proto_identifier import ProtoFullIdentifier
from src.proto_node import ParsedProtoNode, ProtoNode
+class ParsedProtoCommentNode(ParsedProtoNode):
+ node: "ProtoComment"
+ remaining_source: str
+
+
class ProtoComment(ProtoNode):
def __init__(self, value: str):
self.value = value
@@ -22,19 +26,24 @@ def normalize(self) -> Optional["ProtoComment"]:
return None
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoCommentNode"]:
return None
def serialize(self) -> str:
return ""
+class ParsedProtoSingleLineCommentNode(ParsedProtoCommentNode):
+ node: "ProtoSingleLineComment"
+ remaining_source: str
+
+
class ProtoSingleLineComment(ProtoComment):
def __str__(self) -> str:
return f""
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoSingleLineCommentNode"]:
if not proto_source.startswith("//"):
return None
@@ -42,7 +51,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
newline_pos = proto_source.find("\n")
if newline_pos == -1:
newline_pos = len(proto_source)
- return ParsedProtoNode(
+ return ParsedProtoSingleLineCommentNode(
ProtoSingleLineComment(proto_source[:newline_pos]),
proto_source[newline_pos + 1 :],
)
@@ -51,12 +60,17 @@ def serialize(self) -> str:
return f"//{self.value}"
+class ParsedProtoMultiLineCommentNode(ParsedProtoCommentNode):
+ node: "ProtoMultiLineComment"
+ remaining_source: str
+
+
class ProtoMultiLineComment(ProtoComment):
def __str__(self) -> str:
return f""
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoMultiLineCommentNode"]:
if not proto_source.startswith("/*"):
return None
@@ -64,7 +78,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
close_comment_pos = proto_source.find("*/")
if close_comment_pos == -1:
return None
- return ParsedProtoNode(
+ return ParsedProtoMultiLineCommentNode(
ProtoMultiLineComment(proto_source[:close_comment_pos]),
proto_source[close_comment_pos + 2 :],
)
diff --git a/src/proto_constant.py b/src/proto_constant.py
index 03ed8e9..e95fda6 100644
--- a/src/proto_constant.py
+++ b/src/proto_constant.py
@@ -12,6 +12,11 @@
)
+class ParsedProtoConstantNode(ParsedProtoNode):
+ node: "ProtoConstant"
+ remaining_source: str
+
+
class ProtoConstant(ProtoNode):
def __init__(
self,
@@ -32,10 +37,10 @@ def normalize(self) -> "ProtoConstant":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoConstantNode"]:
match = ProtoBool.match(proto_source)
if match is not None:
- return ParsedProtoNode(
+ return ParsedProtoConstantNode(
ProtoConstant(match.node),
match.remaining_source.strip(),
)
@@ -43,41 +48,41 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("+") or proto_source.startswith("-"):
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- match = ProtoInt.match(proto_source[1:])
+ proto_int_match = ProtoInt.match(proto_source[1:])
else:
- match = ProtoInt.match(proto_source)
- if match is not None:
- match.node.sign = sign
- return ParsedProtoNode(
- ProtoConstant(match.node),
- match.remaining_source.strip(),
+ proto_int_match = ProtoInt.match(proto_source)
+ if proto_int_match is not None:
+ proto_int_match.node.sign = sign
+ return ParsedProtoConstantNode(
+ ProtoConstant(proto_int_match.node),
+ proto_int_match.remaining_source.strip(),
)
- sign = ProtoFloatSign.POSITIVE
+ float_sign = ProtoFloatSign.POSITIVE
if proto_source.startswith("+") or proto_source.startswith("-"):
- sign = next(x for x in ProtoFloatSign if x.value == proto_source[0])
- match = ProtoFloat.match(proto_source[1:])
+ float_sign = next(x for x in ProtoFloatSign if x.value == proto_source[0])
+ float_match = ProtoFloat.match(proto_source[1:])
else:
- match = ProtoFloat.match(proto_source)
- if match is not None:
- match.node.sign = sign
- return ParsedProtoNode(
- ProtoConstant(match.node),
- match.remaining_source.strip(),
+ float_match = ProtoFloat.match(proto_source)
+ if float_match is not None:
+ float_match.node.sign = float_sign
+ return ParsedProtoConstantNode(
+ ProtoConstant(float_match.node),
+ float_match.remaining_source.strip(),
)
- match = ProtoFullIdentifier.match(proto_source)
- if match is not None:
- return ParsedProtoNode(
- ProtoConstant(match.node),
- match.remaining_source.strip(),
+ identifier_match = ProtoFullIdentifier.match(proto_source)
+ if identifier_match is not None:
+ return ParsedProtoConstantNode(
+ ProtoConstant(identifier_match.node),
+ identifier_match.remaining_source.strip(),
)
- match = ProtoStringLiteral.match(proto_source)
- if match is not None:
- return ParsedProtoNode(
- ProtoConstant(match.node),
- match.remaining_source.strip(),
+ string_literal_match = ProtoStringLiteral.match(proto_source)
+ if string_literal_match is not None:
+ return ParsedProtoConstantNode(
+ ProtoConstant(string_literal_match.node),
+ string_literal_match.remaining_source.strip(),
)
return None
diff --git a/src/proto_enum.py b/src/proto_enum.py
index 47b658f..e461efb 100644
--- a/src/proto_enum.py
+++ b/src/proto_enum.py
@@ -1,4 +1,4 @@
-from typing import Optional
+from typing import Optional, Sequence
from src.proto_comment import (
ProtoComment,
@@ -8,24 +8,26 @@
from src.proto_identifier import ProtoIdentifier
from src.proto_int import ProtoInt, ProtoIntSign
from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
-from src.proto_option import ProtoOption
+from src.proto_option import ParsedProtoOptionNode, ProtoOption, ProtoOptionDiff
from src.proto_reserved import ProtoReserved
-class ProtoEnumValueOption(ProtoOption):
- def __eq__(self, other) -> bool:
- return super().__eq__(other)
+class ParsedProtoEnumValueOptionNode(ParsedProtoOptionNode):
+ node: "ProtoEnumValueOption"
+ remaining_source: str
+
+class ProtoEnumValueOption(ProtoOption):
def __str__(self) -> str:
return f"<{self.__class__.__name__} name={self.name}, value={self.value}>"
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoEnumValueOptionNode"]:
test_source = "option " + proto_source.strip() + ";"
match = ProtoOption.match(test_source)
if match is None:
return None
- return ParsedProtoNode(
+ return ParsedProtoEnumValueOptionNode(
cls(match.node.name, match.node.value),
match.remaining_source.strip(),
)
@@ -34,6 +36,11 @@ def serialize(self) -> str:
return f"{self.name.serialize()} = {self.value.serialize()}"
+class ParsedProtoEnumValueNode(ParsedProtoNode):
+ node: "ProtoEnumValue"
+ remaining_source: str
+
+
class ProtoEnumValue(ProtoNode):
def __init__(
self,
@@ -62,18 +69,18 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
- def __hash__(self) -> str:
+ def __hash__(self) -> int:
return hash(str(self))
def normalize(self) -> "ProtoEnumValue":
return ProtoEnumValue(
self.identifier,
self.value,
- sorted(self.options, key=lambda o: o.name),
+ sorted(self.options, key=lambda o: str(o.name)),
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoEnumValueNode"]:
match = ProtoIdentifier.match(proto_source)
if match is None:
raise ValueError(f"Proto has invalid enum value name: {proto_source}")
@@ -91,19 +98,19 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("-"):
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- match = ProtoInt.match(proto_source[1:])
+ int_match = ProtoInt.match(proto_source[1:])
else:
- match = ProtoInt.match(proto_source)
- if match is None:
+ int_match = ProtoInt.match(proto_source)
+ if int_match is None:
raise ValueError(
f"Proto has invalid enum value, expecting int: {proto_source}"
)
- match.node.sign = sign
- enum_value = match.node
- proto_source = match.remaining_source.strip()
+ int_match.node.sign = sign
+ enum_value = int_match.node
+ proto_source = int_match.remaining_source.strip()
- options = []
+ options: list[ProtoEnumValueOption] = []
if proto_source.startswith("["):
proto_source = proto_source[1:].strip()
end_bracket = proto_source.find("]")
@@ -112,15 +119,17 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
f"Proto has invalid enum value option syntax, cannot find ]: {proto_source}"
)
for option_part in proto_source[:end_bracket].strip().split(","):
- match = ProtoEnumValueOption.match(option_part.strip())
- if match is None:
+ proto_enum_value_option_match = ProtoEnumValueOption.match(
+ option_part.strip()
+ )
+ if proto_enum_value_option_match is None:
raise ValueError(
f"Proto has invalid enum value option syntax: {proto_source}"
)
- options.append(match.node)
+ options.append(proto_enum_value_option_match.node)
proto_source = proto_source[end_bracket + 1 :].strip()
- return ParsedProtoNode(
+ return ParsedProtoEnumValueNode(
ProtoEnumValue(enum_value_name, enum_value, options), proto_source.strip()
)
@@ -137,7 +146,7 @@ def serialize(self) -> str:
@staticmethod
def diff(
enum: "ProtoEnum", left: "ProtoEnumValue", right: "ProtoEnumValue"
- ) -> list["ProtoNodeDiff"]:
+ ) -> Sequence["ProtoNodeDiff"]:
if left is None and right is not None:
return [ProtoEnumValueAdded(right)]
elif left is not None and right is None:
@@ -148,9 +157,9 @@ def diff(
return []
elif left == right:
return []
- diffs = []
+ diffs: list["ProtoNodeDiff"] = []
# TODO: scope these diffs under ProtoEnumValue
- diffs.extend(ProtoOption.diff_sets(left.options, right.options))
+ diffs.extend(ProtoEnumValueOption.diff_sets(left.options, right.options))
diffs.append(ProtoEnumValueValueChanged(enum, right, left.value))
return diffs
@@ -159,7 +168,7 @@ def diff(
def diff_sets(
enum: "ProtoEnum", left: list["ProtoEnumValue"], right: list["ProtoEnumValue"]
) -> list["ProtoNodeDiff"]:
- diffs = []
+ diffs: list[ProtoNodeDiff] = []
left_names = set(o.identifier.identifier for o in left)
left_values = set(int(o.value) for o in left)
right_names = set(o.identifier.identifier for o in right)
@@ -200,8 +209,12 @@ def __init__(self, name: ProtoIdentifier, nodes: list[ProtoNode]):
self.name = name
self.nodes = nodes
- def __eq__(self, other: "ProtoEnum") -> bool:
- return self.name == other.name and self.nodes == other.nodes
+ def __eq__(self, other: object) -> bool:
+ return (
+ isinstance(other, ProtoEnum)
+ and self.name == other.name
+ and self.nodes == other.nodes
+ )
def __str__(self) -> str:
return f""
@@ -220,13 +233,14 @@ def normalize(self) -> "ProtoEnum":
@staticmethod
def parse_partial_content(partial_enum_content: str) -> ParsedProtoNode:
- for node_type in (
+ supported_types: list[type[ProtoNode]] = [
ProtoSingleLineComment,
ProtoMultiLineComment,
ProtoOption,
ProtoReserved,
ProtoEnumValue,
- ):
+ ]
+ for node_type in supported_types:
try:
match_result = node_type.match(partial_enum_content)
except (ValueError, IndexError, TypeError):
@@ -303,7 +317,7 @@ def diff(left: "ProtoEnum", right: "ProtoEnum") -> list["ProtoNodeDiff"]:
return []
elif left == right:
return []
- diffs = []
+ diffs: list[ProtoNodeDiff] = []
# TODO: scope these diffs under ProtoEnum
diffs.extend(ProtoOption.diff_sets(left.options, right.options))
diffs.extend(ProtoEnumValue.diff_sets(left, left.values, right.values))
@@ -313,7 +327,7 @@ def diff(left: "ProtoEnum", right: "ProtoEnum") -> list["ProtoNodeDiff"]:
def diff_sets(
left: list["ProtoEnum"], right: list["ProtoEnum"]
) -> list["ProtoNodeDiff"]:
- diffs = []
+ diffs: list[ProtoNodeDiff] = []
left_names = set(o.name.identifier for o in left)
right_names = set(o.name.identifier for o in right)
for name in left_names - right_names:
@@ -332,73 +346,62 @@ def diff_sets(
return diffs
-class ProtoEnumAdded(ProtoNodeDiff):
+class ProtoEnumDiff(ProtoNodeDiff):
def __init__(self, enum: ProtoEnum):
self.enum = enum
- def __eq__(self, other: "ProtoEnumAdded") -> bool:
- return isinstance(other, ProtoEnumAdded) and self.enum == other.enum
+ def __eq__(self, other: object) -> bool:
+ return isinstance(other, ProtoEnumDiff) and self.enum == other.enum
def __str__(self) -> str:
- return f""
+ return f"<{self.__class__.__name__} enum={self.enum}>"
-class ProtoEnumRemoved(ProtoNodeDiff):
- def __init__(self, enum: ProtoEnum):
- self.enum = enum
+class ProtoEnumAdded(ProtoEnumDiff):
+ pass
- def __eq__(self, other: "ProtoEnumRemoved") -> bool:
- return isinstance(other, ProtoEnumRemoved) and self.enum == other.enum
- def __str__(self) -> str:
- return f""
+class ProtoEnumRemoved(ProtoEnumDiff):
+ pass
-class ProtoEnumValueAdded(ProtoNodeDiff):
+class ProtoEnumValueDiff(ProtoEnumDiff):
def __init__(self, enum: "ProtoEnum", enum_value: "ProtoEnumValue"):
- self.enum = enum
+ super().__init__(enum)
self.enum_value = enum_value
- def __eq__(self, other: "ProtoEnumValueAdded") -> bool:
+ def __eq__(self, other: object) -> bool:
return (
- isinstance(other, ProtoEnumValueAdded)
- and self.enum == other.enum
+ super().__eq__(other)
+ and isinstance(other, ProtoEnumValueDiff)
and self.enum_value == other.enum_value
)
def __str__(self) -> str:
- return f""
+ return (
+ f"<{self.__class__.__name__} enum={self.enum} enum_value={self.enum_value}>"
+ )
-class ProtoEnumValueRemoved(ProtoNodeDiff):
- def __init__(self, enum: "ProtoEnum", enum_value: "ProtoEnumValue"):
- self.enum = enum
- self.enum_value = enum_value
+class ProtoEnumValueAdded(ProtoEnumValueDiff):
+ pass
- def __eq__(self, other: "ProtoEnumValueRemoved") -> bool:
- return (
- isinstance(other, ProtoEnumValueRemoved)
- and self.enum == other.enum
- and self.enum_value == other.enum_value
- )
- def __str__(self) -> str:
- return f""
+class ProtoEnumValueRemoved(ProtoEnumValueDiff):
+ pass
-class ProtoEnumValueNameChanged(ProtoNodeDiff):
+class ProtoEnumValueNameChanged(ProtoEnumValueDiff):
def __init__(
self, enum: ProtoEnum, enum_value: ProtoEnumValue, new_name: ProtoIdentifier
):
- self.enum = enum
- self.enum_value = enum_value
+ super().__init__(enum, enum_value)
self.new_name = new_name
- def __eq__(self, other: "ProtoEnumValueNameChanged") -> bool:
+ def __eq__(self, other: object) -> bool:
return (
- isinstance(other, ProtoEnumValueNameChanged)
- and self.enum == other.enum
- and self.enum_value == other.enum_value
+ super().__eq__(other)
+ and isinstance(other, ProtoEnumValueNameChanged)
and self.new_name == other.new_name
)
@@ -406,19 +409,17 @@ def __str__(self) -> str:
return f""
-class ProtoEnumValueValueChanged(ProtoNodeDiff):
+class ProtoEnumValueValueChanged(ProtoEnumValueDiff):
def __init__(
self, enum: ProtoEnum, enum_value: ProtoEnumValue, new_value: ProtoInt
):
- self.enum = enum
- self.enum_value = enum_value
+ super().__init__(enum, enum_value)
self.new_value = new_value
- def __eq__(self, other: "ProtoEnumValueValueChanged") -> bool:
+ def __eq__(self, other: object) -> bool:
return (
- isinstance(other, ProtoEnumValueValueChanged)
- and self.enum == other.enum
- and self.enum_value == other.enum_value
+ super().__eq__(other)
+ and isinstance(other, ProtoEnumValueValueChanged)
and self.new_value == other.new_value
)
diff --git a/src/proto_extend.py b/src/proto_extend.py
index aff1a39..cb563a3 100644
--- a/src/proto_extend.py
+++ b/src/proto_extend.py
@@ -30,16 +30,17 @@ def normalize(self) -> "ProtoExtend":
)
return ProtoExtend(
name=self.name,
- nodes=sorted(non_comment_nodes, key=lambda f: int(f.number)),
+ nodes=sorted(non_comment_nodes, key=lambda f: str(f)),
)
@staticmethod
def parse_partial_content(partial_content: str) -> ParsedProtoNode:
- for node_type in (
+ supported_types: list[type[ProtoNode]] = [
ProtoSingleLineComment,
ProtoMultiLineComment,
ProtoMessageField,
- ):
+ ]
+ for node_type in supported_types:
try:
match_result = node_type.match(partial_content)
except (ValueError, IndexError, TypeError):
diff --git a/src/proto_extensions.py b/src/proto_extensions.py
index 2008bff..e4fb2f3 100644
--- a/src/proto_extensions.py
+++ b/src/proto_extensions.py
@@ -25,8 +25,7 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoExtensions":
# sort the ranges.
return ProtoExtensions(
- sorted(self.ranges, key=lambda r: r.min),
- self.quote_type,
+ sorted(self.ranges, key=lambda r: int(r.min)),
)
@classmethod
diff --git a/src/proto_file.py b/src/proto_file.py
index f70a210..adcd7f8 100644
--- a/src/proto_file.py
+++ b/src/proto_file.py
@@ -1,4 +1,4 @@
-from typing import Optional
+from typing import Optional, Sequence
from src.proto_enum import ProtoEnum
from src.proto_import import ProtoImport
@@ -42,7 +42,7 @@ def messages(self) -> list[ProtoMessage]:
def serialize(self) -> str:
serialized_parts = [self.syntax.serialize()]
- previous_type = self.syntax.__class__
+ previous_type: type[ProtoNode] = self.syntax.__class__
for node in self.nodes:
# Attempt to group up lines of the same type.
if node.__class__ != previous_type:
@@ -52,8 +52,8 @@ def serialize(self) -> str:
return "\n".join(serialized_parts)
- def diff(self, other: "ProtoFile") -> list[ProtoNodeDiff]:
- diffs = []
+ def diff(self, other: "ProtoFile") -> Sequence[ProtoNodeDiff]:
+ diffs: list[ProtoNodeDiff] = []
diffs.extend(ProtoSyntax.diff(self.syntax, other.syntax))
diffs.extend(ProtoImport.diff_sets(self.imports, other.imports))
diffs.extend(ProtoPackage.diff(self.package, other.package))
diff --git a/src/proto_float.py b/src/proto_float.py
index 65913ce..a139b11 100644
--- a/src/proto_float.py
+++ b/src/proto_float.py
@@ -11,6 +11,11 @@ class ProtoFloatSign(Enum):
NEGATIVE = "-"
+class ParsedProtoFloatNode(ParsedProtoNode):
+ node: "ProtoFloat"
+ remaining_source: str
+
+
class ProtoFloat(ProtoNode):
SIGNS = set("+-")
DIGITS = ProtoInt.DECIMAL
@@ -38,14 +43,14 @@ def normalize(self) -> "ProtoFloat":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoFloatNode"]:
if proto_source.startswith("inf"):
proto_source = proto_source[3:]
if proto_source and proto_source[0] in ProtoIdentifier.ALL:
raise ValueError(
f"Proto has invalid float, invalid post-inf character: {proto_source}"
)
- return ParsedProtoNode(
+ return ParsedProtoFloatNode(
ProtoFloat(float("inf"), ProtoFloatSign.POSITIVE), proto_source.strip()
)
@@ -55,7 +60,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
raise ValueError(
f"Proto has invalid float, invalid post-nan character: {proto_source}"
)
- return ParsedProtoNode(
+ return ParsedProtoFloatNode(
ProtoFloat(float("nan"), ProtoFloatSign.POSITIVE), proto_source.strip()
)
@@ -107,7 +112,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
base *= pow(10, sign * int(proto_source[: i + 1]))
proto_source = proto_source[i + 1 :]
- return ParsedProtoNode(
+ return ParsedProtoFloatNode(
ProtoFloat(base, ProtoFloatSign.POSITIVE), proto_source.strip()
)
diff --git a/src/proto_identifier.py b/src/proto_identifier.py
index cc55aaf..ee5368b 100644
--- a/src/proto_identifier.py
+++ b/src/proto_identifier.py
@@ -3,6 +3,21 @@
from src.proto_node import ParsedProtoNode, ProtoNode
+class ParsedProtoIdentifierNode(ParsedProtoNode):
+ node: "ProtoIdentifier"
+ remaining_source: str
+
+
+class ParsedProtoFullIdentifierNode(ParsedProtoIdentifierNode):
+ node: "ProtoFullIdentifier"
+ remaining_source: str
+
+
+class ParsedProtoEnumOrMessageIdentifierNode(ParsedProtoIdentifierNode):
+ node: "ProtoEnumOrMessageIdentifier"
+ remaining_source: str
+
+
class ProtoIdentifier(ProtoNode):
ALPHABETICAL = set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
STARTING = ALPHABETICAL | set("_")
@@ -27,16 +42,16 @@ def normalize(self) -> "ProtoIdentifier":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoIdentifierNode"]:
if proto_source[0] not in ProtoIdentifier.STARTING:
return None
for i, c in enumerate(proto_source):
if c not in ProtoIdentifier.ALL:
- return ParsedProtoNode(
+ return ParsedProtoIdentifierNode(
ProtoIdentifier(proto_source[:i]), proto_source[i:]
)
- return ParsedProtoNode(ProtoIdentifier(proto_source), "")
+ return ParsedProtoIdentifierNode(ProtoIdentifier(proto_source), "")
def serialize(self) -> str:
return self.identifier
@@ -47,7 +62,7 @@ class ProtoFullIdentifier(ProtoIdentifier):
ALL = ProtoIdentifier.ALL | set(".")
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoFullIdentifierNode"]:
if proto_source[0] not in ProtoFullIdentifier.STARTING:
return None
@@ -61,7 +76,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
f"Proto source has invalid identifier, expecting alphanumeric after .: {proto_source}"
)
identifier_parts.append(proto_source[last_part_start:i])
- return ParsedProtoNode(
+ return ParsedProtoFullIdentifierNode(
ProtoFullIdentifier(".".join(identifier_parts)), proto_source[i:]
)
elif c == ".":
@@ -74,7 +89,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
f"Proto source has invalid identifier, expecting alphanumeric after .: {proto_source}"
)
identifier_parts.append(proto_source[last_part_start:])
- return ParsedProtoNode(ProtoFullIdentifier(".".join(identifier_parts)), "")
+ return ParsedProtoFullIdentifierNode(
+ ProtoFullIdentifier(".".join(identifier_parts)), ""
+ )
class ProtoEnumOrMessageIdentifier(ProtoIdentifier):
@@ -82,19 +99,22 @@ class ProtoEnumOrMessageIdentifier(ProtoIdentifier):
ALL = ProtoIdentifier.ALL | set(".")
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, proto_source: str
+ ) -> Optional["ParsedProtoEnumOrMessageIdentifierNode"]:
if proto_source[0] == ".":
matched_source = proto_source[1:]
else:
matched_source = proto_source
- match = ProtoFullIdentifier.match(matched_source)
- if match is not None:
- match = ParsedProtoNode(
- ProtoEnumOrMessageIdentifier(match.node.identifier),
- match.remaining_source,
+ identifier_match = ProtoFullIdentifier.match(matched_source)
+ if identifier_match is not None:
+ match = ParsedProtoEnumOrMessageIdentifierNode(
+ ProtoEnumOrMessageIdentifier(identifier_match.node.identifier),
+ identifier_match.remaining_source,
)
if proto_source[0] == ".":
match.node.identifier = "." + match.node.identifier
- return match
+ return match
+ return identifier_match
diff --git a/src/proto_import.py b/src/proto_import.py
index f3a5682..dc67721 100644
--- a/src/proto_import.py
+++ b/src/proto_import.py
@@ -25,7 +25,7 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
- def __dict__(self) -> dict:
+ def __dict__(self):
return {
"path": self.path.serialize(),
"weak": self.weak,
@@ -80,7 +80,7 @@ def serialize(self) -> str:
def diff_sets(
left: list["ProtoImport"], right: list["ProtoImport"]
) -> list["ProtoNodeDiff"]:
- diffs = []
+ diffs: list[ProtoNodeDiff] = []
left_names = set(i.path for i in left)
right_names = set(i.path for i in right)
for name in left_names - right_names:
@@ -106,8 +106,11 @@ class ProtoImportAdded(ProtoNodeDiff):
def __init__(self, proto_import: ProtoImport):
self.proto_import = proto_import
- def __eq__(self, other: "ProtoImportAdded") -> bool:
- return self.proto_import == other.proto_import
+ def __eq__(self, other: object) -> bool:
+ return (
+ isinstance(other, ProtoImportAdded)
+ and self.proto_import == other.proto_import
+ )
class ProtoImportRemoved(ProtoImportAdded):
@@ -118,10 +121,6 @@ class ProtoImportMadeWeak(ProtoImportAdded):
pass
-class ProtoImportMadeWeak(ProtoImportAdded):
- pass
-
-
class ProtoImportMadeNonWeak(ProtoImportAdded):
pass
diff --git a/src/proto_int.py b/src/proto_int.py
index dd1e01e..67aa7ba 100644
--- a/src/proto_int.py
+++ b/src/proto_int.py
@@ -10,6 +10,11 @@ class ProtoIntSign(Enum):
NEGATIVE = "-"
+class ParsedProtoIntNode(ParsedProtoNode):
+ node: "ProtoInt"
+ remaining_source: str
+
+
class ProtoInt(ProtoNode):
OCTAL = set("01234567")
DECIMAL = OCTAL | set("89")
@@ -38,7 +43,7 @@ def normalize(self) -> "ProtoInt":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoIntNode"]:
if proto_source[0] not in ProtoInt.DECIMAL:
return None
@@ -58,7 +63,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
value = int(f"0x{proto_source[:i + 1]}", 16)
except ValueError:
raise ValueError(f"Proto has invalid hex: {proto_source}")
- return ParsedProtoNode(
+ return ParsedProtoIntNode(
ProtoInt(value, ProtoIntSign.POSITIVE),
proto_source[i + 1 :].strip(),
)
@@ -74,7 +79,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
value = int(f"0{proto_source[:i + 1]}", 8)
except ValueError:
raise ValueError(f"Proto has invalid octal: {proto_source}")
- return ParsedProtoNode(
+ return ParsedProtoIntNode(
ProtoInt(value, ProtoIntSign.POSITIVE),
proto_source[i + 1 :].strip(),
)
@@ -91,7 +96,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
except ValueError:
return None
- return ParsedProtoNode(
+ return ParsedProtoIntNode(
ProtoInt(value, ProtoIntSign.POSITIVE),
proto_source[i + 1 :].strip(),
)
diff --git a/src/proto_message.py b/src/proto_message.py
index b2fb80c..191e127 100644
--- a/src/proto_message.py
+++ b/src/proto_message.py
@@ -1,7 +1,9 @@
from enum import Enum
-from typing import Optional
+from typing import Optional, Sequence
from src.proto_comment import (
+ ParsedProtoMultiLineCommentNode,
+ ParsedProtoSingleLineCommentNode,
ProtoComment,
ProtoMultiLineComment,
ProtoSingleLineComment,
@@ -16,19 +18,33 @@
)
from src.proto_int import ProtoInt
from src.proto_message_field import (
+ ParsedProtoMessageFieldNode,
ProtoMessageField,
ProtoMessageFieldOption,
ProtoMessageFieldTypesEnum,
)
from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
-from src.proto_option import ProtoOption
+from src.proto_option import ParsedProtoOptionNode, ProtoOption
from src.proto_reserved import ProtoReserved
-ProtoOneOfNodeTypes = ProtoOption | ProtoMessageField
+ProtoOneOfNodeTypes = (
+ ProtoOption | ProtoMessageField | ProtoSingleLineComment | ProtoMultiLineComment
+)
+ProtoParsedOneOfNodeTypes = (
+ ParsedProtoOptionNode
+ | ParsedProtoMessageFieldNode
+ | ParsedProtoSingleLineCommentNode
+ | ParsedProtoMultiLineCommentNode
+)
+
+
+class ParsedProtoOneOfNode(ParsedProtoNode):
+ node: "ProtoOneOf"
+ remaining_source: str
class ProtoOneOf(ProtoNode):
- def __init__(self, name: ProtoIdentifier, nodes: list[ProtoOneOfNodeTypes]):
+ def __init__(self, name: ProtoIdentifier, nodes: Sequence[ProtoOneOfNodeTypes]):
self.name = name
self.nodes = nodes
@@ -71,13 +87,14 @@ def normalize(self) -> "ProtoOneOf":
)
@staticmethod
- def parse_partial_content(partial_oneof_content: str) -> ParsedProtoNode:
- for node_type in (
+ def parse_partial_content(partial_oneof_content: str) -> ProtoParsedOneOfNodeTypes:
+ supported_types: list[type[ProtoOneOfNodeTypes]] = [
ProtoMessageField,
ProtoOption,
ProtoSingleLineComment,
ProtoMultiLineComment,
- ):
+ ]
+ for node_type in supported_types:
try:
match_result = node_type.match(partial_oneof_content)
except (ValueError, IndexError, TypeError):
@@ -91,7 +108,7 @@ def parse_partial_content(partial_oneof_content: str) -> ParsedProtoNode:
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoOneOfNode"]:
if not proto_source.startswith("oneof "):
return None
@@ -127,7 +144,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
parsed_tree.append(match_result.node)
proto_source = match_result.remaining_source.strip()
- return ParsedProtoNode(ProtoOneOf(oneof_name, nodes=parsed_tree), proto_source)
+ return ParsedProtoOneOfNode(
+ ProtoOneOf(oneof_name, nodes=parsed_tree), proto_source
+ )
@property
def options(self) -> list[ProtoOption]:
@@ -167,7 +186,7 @@ def __init__(
value_type: ProtoMapValueTypesEnum,
name: ProtoIdentifier,
number: ProtoInt,
- enum_or_message_type_name: Optional[ProtoFullIdentifier] = None,
+ enum_or_message_type_name: Optional[ProtoEnumOrMessageIdentifier] = None,
options: Optional[list[ProtoMessageFieldOption]] = None,
):
self.key_type = key_type
@@ -256,22 +275,22 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
proto_source = proto_source[1:].strip()
# Try to match the map field's name.
- match = ProtoIdentifier.match(proto_source)
- if match is None:
+ identifier_match = ProtoIdentifier.match(proto_source)
+ if identifier_match is None:
return None
- name = match.node
- proto_source = match.remaining_source.strip()
+ name = identifier_match.node
+ proto_source = identifier_match.remaining_source.strip()
if not proto_source.startswith("="):
return None
proto_source = proto_source[1:].strip()
# Try to match the map field number.
- match = ProtoInt.match(proto_source)
- if match is None:
+ int_match = ProtoInt.match(proto_source)
+ if int_match is None:
return None
- number = match.node
- proto_source = match.remaining_source.strip()
+ number = int_match.node
+ proto_source = int_match.remaining_source.strip()
# Try to match map field options, if any.
options = []
@@ -283,12 +302,14 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
f"Proto has invalid map field option syntax, cannot find ]: {proto_source}"
)
for option_part in proto_source[:end_bracket].strip().split(","):
- match = ProtoMessageFieldOption.match(option_part.strip())
- if match is None:
+ message_field_option_match = ProtoMessageFieldOption.match(
+ option_part.strip()
+ )
+ if message_field_option_match is None:
raise ValueError(
f"Proto has invalid map field option syntax: {proto_source}"
)
- options.append(match.node)
+ options.append(message_field_option_match.node)
proto_source = proto_source[end_bracket + 1 :].strip()
if not proto_source.startswith(";"):
@@ -310,6 +331,10 @@ def serialize(self) -> str:
]
if self.value_type == ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE:
+ if self.enum_or_message_type_name is None:
+ raise ValueError(
+ f"Enum or message type name was not set for: {str(self)}"
+ )
serialized_parts.append(f"{self.enum_or_message_type_name.serialize()}>")
else:
serialized_parts.append(f"{self.value_type.value}>")
@@ -331,7 +356,7 @@ def serialize(self) -> str:
class ProtoMessage(ProtoNode):
- def __init__(self, name: ProtoIdentifier, nodes: list[ProtoNode]):
+ def __init__(self, name: ProtoIdentifier, nodes: Sequence[ProtoNode]):
self.name = name
self.nodes = nodes
@@ -353,20 +378,19 @@ def normalize(self) -> "ProtoMessage":
enums = []
messages = []
fields = []
+ oneofs = []
reserveds = []
for node in non_comment_nodes:
if isinstance(node, ProtoOption):
options.append(node.normalize())
elif isinstance(node, ProtoEnum):
- options.append(node.normalize())
+ enums.append(node.normalize())
elif isinstance(node, ProtoMessage):
messages.append(node.normalize())
- elif (
- isinstance(node, ProtoMessageField)
- or isinstance(node, ProtoOneOf)
- or isinstance(node, ProtoMap)
- ):
+ elif isinstance(node, ProtoMessageField) or isinstance(node, ProtoMap):
fields.append(node.normalize())
+ elif isinstance(node, ProtoOneOf):
+ oneofs.append(node.normalize())
elif isinstance(node, ProtoReserved):
reserveds.append(node.normalize())
else:
@@ -379,7 +403,8 @@ def normalize(self) -> "ProtoMessage":
+ sorted(enums, key=lambda e: str(e))
+ sorted(messages, key=lambda m: str(m))
+ sorted(fields, key=lambda f: int(f.number))
- + sorted(reserveds, key=lambda r: (r.min, r.max))
+ + sorted(oneofs, key=lambda o: str(o))
+ + sorted(reserveds, key=lambda r: int(r.min))
)
return ProtoMessage(
@@ -389,7 +414,7 @@ def normalize(self) -> "ProtoMessage":
@staticmethod
def parse_partial_content(partial_message_content: str) -> ParsedProtoNode:
- for node_type in (
+ supported_types: list[type[ProtoNode]] = [
ProtoSingleLineComment,
ProtoMultiLineComment,
ProtoEnum,
@@ -401,7 +426,8 @@ def parse_partial_content(partial_message_content: str) -> ParsedProtoNode:
ProtoMessageField,
ProtoOneOf,
ProtoMap,
- ):
+ ]
+ for node_type in supported_types:
try:
match_result = node_type.match(partial_message_content)
except (ValueError, IndexError, TypeError):
@@ -463,7 +489,7 @@ def serialize(self) -> str:
return "\n".join(serialize_parts)
@staticmethod
- def diff(left: "ProtoMessage", right: "ProtoMessage") -> list["ProtoNodeDiff"]:
+ def diff(left: "ProtoMessage", right: "ProtoMessage") -> Sequence["ProtoNodeDiff"]:
if left is None and right is not None:
return [ProtoMessageAdded(right)]
elif left is not None and right is None:
@@ -482,8 +508,8 @@ def diff(left: "ProtoMessage", right: "ProtoMessage") -> list["ProtoNodeDiff"]:
@staticmethod
def diff_sets(
left: list["ProtoMessage"], right: list["ProtoMessage"]
- ) -> list["ProtoNodeDiff"]:
- diffs = []
+ ) -> Sequence["ProtoNodeDiff"]:
+ diffs: list[ProtoNodeDiff] = []
left_names = set(o.name.identifier for o in left)
right_names = set(o.name.identifier for o in right)
for name in left_names - right_names:
@@ -502,23 +528,22 @@ def diff_sets(
return diffs
-class ProtoMessageAdded(ProtoNodeDiff):
+class ProtoMessageDiff(ProtoNodeDiff):
def __init__(self, message: ProtoMessage):
self.message = message
- def __eq__(self, other: "ProtoMessageAdded") -> bool:
- return isinstance(other, ProtoMessageAdded) and self.message == other.message
+ def __eq__(self, other: object) -> bool:
+ return isinstance(other, ProtoMessageDiff) and self.message == other.message
def __str__(self) -> str:
- return f""
+ return f"<{self.__class__.__name__} message={self.message}>"
-class ProtoMessageRemoved(ProtoNodeDiff):
- def __init__(self, message: ProtoMessage):
- self.message = message
+class ProtoMessageAdded(ProtoMessageDiff):
+ def __eq__(self, other: object) -> bool:
+ return super().__eq__(other) and isinstance(other, ProtoMessageAdded)
- def __eq__(self, other: "ProtoMessageRemoved") -> bool:
- return isinstance(other, ProtoMessageRemoved) and self.message == other.message
- def __str__(self) -> str:
- return f""
+class ProtoMessageRemoved(ProtoMessageDiff):
+ def __eq__(self, other: object) -> bool:
+ return super().__eq__(other) and isinstance(other, ProtoMessageRemoved)
diff --git a/src/proto_message_field.py b/src/proto_message_field.py
index b2cbba0..97f75ce 100644
--- a/src/proto_message_field.py
+++ b/src/proto_message_field.py
@@ -1,18 +1,27 @@
from enum import Enum
from typing import Optional
-from src.proto_enum import ProtoEnumValueOption
-from src.proto_identifier import (
- ProtoEnumOrMessageIdentifier,
- ProtoFullIdentifier,
- ProtoIdentifier,
-)
+from src.proto_enum import ParsedProtoEnumValueOptionNode, ProtoEnumValueOption
+from src.proto_identifier import ProtoEnumOrMessageIdentifier, ProtoIdentifier
from src.proto_int import ProtoInt
from src.proto_node import ParsedProtoNode, ProtoNode
+class ParsedProtoMessageFieldOptionNode(ParsedProtoEnumValueOptionNode):
+ node: "ProtoMessageFieldOption"
+ remaining_source: str
+
+
class ProtoMessageFieldOption(ProtoEnumValueOption):
- pass
+ @classmethod
+ def match(cls, proto_source: str) -> Optional["ParsedProtoMessageFieldOptionNode"]:
+ match = super().match(proto_source)
+ if match is None:
+ return None
+ return ParsedProtoMessageFieldOptionNode(
+ match.node,
+ match.remaining_source.strip(),
+ )
class ProtoMessageFieldTypesEnum(Enum):
@@ -34,6 +43,11 @@ class ProtoMessageFieldTypesEnum(Enum):
ENUM_OR_MESSAGE = "enum_or_message"
+class ParsedProtoMessageFieldNode(ParsedProtoNode):
+ node: "ProtoMessageField"
+ remaining_source: str
+
+
class ProtoMessageField(ProtoNode):
def __init__(
self,
@@ -42,7 +56,7 @@ def __init__(
number: ProtoInt,
repeated: bool = False,
optional: bool = False,
- enum_or_message_type_name: Optional[ProtoFullIdentifier] = None,
+ enum_or_message_type_name: Optional[ProtoEnumOrMessageIdentifier] = None,
options: Optional[list[ProtoMessageFieldOption]] = None,
):
self.type = type
@@ -88,11 +102,11 @@ def normalize(self) -> "ProtoMessageField":
repeated=self.repeated,
optional=self.optional,
enum_or_message_type_name=self.enum_or_message_type_name,
- options=sorted(self.options, key=lambda o: o.name),
+ options=sorted(self.options, key=lambda o: str(o.name)),
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoMessageFieldNode"]:
# First, try to match the optional repeated.
repeated = False
if proto_source.startswith("repeated "):
@@ -130,22 +144,22 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
proto_source = match.remaining_source.strip()
# Match the field name.
- match = ProtoIdentifier.match(proto_source)
- if match is None:
+ identifier_match = ProtoIdentifier.match(proto_source)
+ if identifier_match is None:
return None
- name = match.node
- proto_source = match.remaining_source.strip()
+ name = identifier_match.node
+ proto_source = identifier_match.remaining_source.strip()
if not proto_source.startswith("= "):
return None
proto_source = proto_source[2:].strip()
# Match the field number.
- match = ProtoInt.match(proto_source)
- if match is None:
+ int_match = ProtoInt.match(proto_source)
+ if int_match is None:
return None
- number = match.node
- proto_source = match.remaining_source.strip()
+ number = int_match.node
+ proto_source = int_match.remaining_source.strip()
options = []
if proto_source.startswith("["):
@@ -156,12 +170,14 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
f"Proto has invalid message field option syntax, cannot find ]: {proto_source}"
)
for option_part in proto_source[:end_bracket].strip().split(","):
- match = ProtoMessageFieldOption.match(option_part.strip())
- if match is None:
+ message_field_option_match = ProtoMessageFieldOption.match(
+ option_part.strip()
+ )
+ if message_field_option_match is None:
raise ValueError(
f"Proto has invalid message field option syntax: {proto_source}"
)
- options.append(match.node)
+ options.append(message_field_option_match.node)
proto_source = proto_source[end_bracket + 1 :].strip()
if not proto_source.startswith(";"):
@@ -169,7 +185,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
f"Proto has invalid message field syntax, missing ending ;:{proto_source}"
)
- return ParsedProtoNode(
+ return ParsedProtoMessageFieldNode(
ProtoMessageField(
matched_type,
name,
@@ -188,6 +204,10 @@ def serialize(self) -> str:
serialized_parts.append("repeated")
if self.type == ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE:
+ if self.enum_or_message_type_name is None:
+ raise ValueError(
+ f"Enum or message type name was not set for: {str(self)}"
+ )
serialized_parts.append(self.enum_or_message_type_name.serialize())
else:
serialized_parts.append(self.type.value)
diff --git a/src/proto_node.py b/src/proto_node.py
index 162fe74..37c36e8 100644
--- a/src/proto_node.py
+++ b/src/proto_node.py
@@ -32,5 +32,5 @@ class ProtoNodeDiff(abc.ABC):
def __repr__(self) -> str:
return str(self)
- def __hash__(self) -> str:
+ def __hash__(self) -> int:
return hash(str(self))
diff --git a/src/proto_option.py b/src/proto_option.py
index 58c02cf..a780351 100644
--- a/src/proto_option.py
+++ b/src/proto_option.py
@@ -1,4 +1,4 @@
-from typing import Optional
+from typing import Optional, Sequence
from src.proto_constant import ProtoConstant
from src.proto_identifier import (
@@ -9,6 +9,11 @@
from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
+class ParsedProtoOptionNode(ParsedProtoNode):
+ node: "ProtoOption"
+ remaining_source: str
+
+
class ProtoOption(ProtoNode):
def __init__(self, name: ProtoIdentifier, value: ProtoConstant):
self.name = name
@@ -30,7 +35,7 @@ def normalize(self) -> "ProtoOption":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoOptionNode"]:
if not proto_source.startswith("option "):
return None
proto_source = proto_source[7:]
@@ -39,27 +44,32 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
if proto_source.startswith("("):
proto_source = proto_source[1:]
match = ProtoFullIdentifier.match(proto_source)
- if not match or not match.remaining_source.startswith(")"):
+ if match is None or not match.remaining_source.startswith(")"):
# This might be a regular identifier.
- match = ProtoIdentifier.match(proto_source)
- if not match or not match.remaining_source.startswith(")"):
+ identifier_match = ProtoIdentifier.match(proto_source)
+ if (
+ not identifier_match
+ or not identifier_match.remaining_source.startswith(")")
+ ):
raise ValueError(
f"Proto has invalid option when expecting ): {proto_source}"
)
- name_parts.append(ProtoIdentifier(f"({match.node.identifier})"))
+ name_parts.append(
+ ProtoIdentifier(f"({identifier_match.node.identifier})")
+ )
+ proto_source = identifier_match.remaining_source[1:]
else:
name_parts.append(ProtoFullIdentifier(f"({match.node.identifier})"))
-
- proto_source = match.remaining_source[1:]
+ proto_source = match.remaining_source[1:]
while True:
- match = ProtoEnumOrMessageIdentifier.match(proto_source)
- if match is None:
- match = ProtoIdentifier.match(proto_source)
- if match is None:
+ identifier_match = ProtoEnumOrMessageIdentifier.match(proto_source)
+ if identifier_match is None:
+ identifier_match = ProtoIdentifier.match(proto_source)
+ if identifier_match is None:
break
- name_parts.append(match.node)
- proto_source = match.remaining_source
+ name_parts.append(identifier_match.node)
+ proto_source = identifier_match.remaining_source
proto_source = proto_source.strip()
if not proto_source.startswith("="):
@@ -67,27 +77,28 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
f"Proto has invalid option when expecting =: {proto_source}"
)
proto_source = proto_source[1:].strip()
- match = ProtoConstant.match(proto_source)
- if not match:
+ constant_match = ProtoConstant.match(proto_source)
+ if constant_match is None:
raise ValueError(
f"Proto has invalid option when expecting constant: {proto_source}"
)
- proto_source = match.remaining_source
- if not match.remaining_source.startswith(";"):
+ proto_source = constant_match.remaining_source
+ if not constant_match.remaining_source.startswith(";"):
raise ValueError(
f"Proto has invalid option when expecting ;: {proto_source}"
)
+ identifier: ProtoFullIdentifier | ProtoIdentifier
if len(name_parts) > 1:
identifier = ProtoFullIdentifier("".join(x.identifier for x in name_parts))
else:
identifier = ProtoIdentifier(name_parts[0].identifier)
- return ParsedProtoNode(
+ return ParsedProtoOptionNode(
ProtoOption(
name=identifier,
- value=match.node,
+ value=constant_match.node,
),
proto_source[1:],
)
@@ -96,7 +107,7 @@ def serialize(self) -> str:
return f"option {self.name.serialize()} = {self.value.serialize()};"
@staticmethod
- def diff(left: "ProtoOption", right: "ProtoOption") -> list["ProtoNodeDiff"]:
+ def diff(left: "ProtoOption", right: "ProtoOption") -> Sequence["ProtoOptionDiff"]:
if left is None and right is not None:
return [ProtoOptionAdded(right)]
elif left is not None and right is None:
@@ -111,9 +122,9 @@ def diff(left: "ProtoOption", right: "ProtoOption") -> list["ProtoNodeDiff"]:
@staticmethod
def diff_sets(
- left: list["ProtoOption"], right: list["ProtoOption"]
- ) -> list["ProtoNodeDiff"]:
- diffs = []
+ left: Sequence["ProtoOption"], right: Sequence["ProtoOption"]
+ ) -> list["ProtoOptionDiff"]:
+ diffs: list[ProtoOptionDiff] = []
left_names = set(o.name.identifier for o in left)
right_names = set(o.name.identifier for o in right)
for name in left_names - right_names:
@@ -132,13 +143,19 @@ def diff_sets(
return diffs
-class ProtoOptionValueChanged(ProtoNodeDiff):
- def __init__(self, name: ProtoIdentifier, left: str, right: str):
+class ProtoOptionDiff(ProtoNodeDiff):
+ pass
+
+
+class ProtoOptionValueChanged(ProtoOptionDiff):
+ def __init__(
+ self, name: ProtoIdentifier, left: ProtoConstant, right: ProtoConstant
+ ):
self.name = name
self.left = left
self.right = right
- def __eq__(self, other: "ProtoOptionValueChanged") -> bool:
+ def __eq__(self, other: object) -> bool:
return (
isinstance(other, ProtoOptionValueChanged)
and self.name == other.name
@@ -150,22 +167,22 @@ def __str__(self) -> str:
return f""
-class ProtoOptionAdded(ProtoNodeDiff):
- def __init__(self, left: str):
+class ProtoOptionAdded(ProtoOptionDiff):
+ def __init__(self, left: ProtoOption):
self.left = left
- def __eq__(self, other: "ProtoOptionAdded") -> bool:
+ def __eq__(self, other: object) -> bool:
return isinstance(other, ProtoOptionAdded) and self.left == other.left
def __str__(self) -> str:
return f""
-class ProtoOptionRemoved(ProtoNodeDiff):
- def __init__(self, right: str):
+class ProtoOptionRemoved(ProtoOptionDiff):
+ def __init__(self, right: ProtoOption):
self.right = right
- def __eq__(self, other: "ProtoOptionRemoved") -> bool:
+ def __eq__(self, other: object) -> bool:
return isinstance(other, ProtoOptionRemoved) and self.right == other.right
def __str__(self) -> str:
diff --git a/src/proto_package.py b/src/proto_package.py
index 569ee2c..7559cd6 100644
--- a/src/proto_package.py
+++ b/src/proto_package.py
@@ -50,36 +50,44 @@ def serialize(self) -> str:
return f"package {self.package};"
@staticmethod
- def diff(left: "ProtoPackage", right: "ProtoPackage") -> list["ProtoNodeDiff"]:
+ def diff(
+ left: Optional["ProtoPackage"], right: Optional["ProtoPackage"]
+ ) -> list["ProtoNodeDiff"]:
if left == right:
return []
elif left is not None and right is None:
return [ProtoPackageAdded(left)]
elif left is None and right is not None:
return [ProtoPackageRemoved(right)]
+
+ assert left is not None and right is not None
return [ProtoPackageChanged(left, right)]
class ProtoPackageChanged(ProtoNodeDiff):
- def __init__(self, left: str, right: str):
+ def __init__(self, left: ProtoPackage, right: ProtoPackage):
self.left = left
self.right = right
- def __eq__(self, other: "ProtoPackageChanged") -> bool:
- return self.left == other.left and self.right == other.right
+ def __eq__(self, other: object) -> bool:
+ return (
+ isinstance(other, ProtoPackageChanged)
+ and self.left == other.left
+ and self.right == other.right
+ )
class ProtoPackageAdded(ProtoNodeDiff):
- def __init__(self, left: str):
+ def __init__(self, left: ProtoPackage):
self.left = left
- def __eq__(self, other: "ProtoPackageAdded") -> bool:
- return self.left == other.left
+ def __eq__(self, other: object) -> bool:
+ return isinstance(other, ProtoPackageAdded) and self.left == other.left
class ProtoPackageRemoved(ProtoNodeDiff):
- def __init__(self, right: str):
+ def __init__(self, right: ProtoPackage):
self.right = right
- def __eq__(self, other: "ProtoPackageRemoved") -> bool:
- return self.right == other.right
+ def __eq__(self, other: object) -> bool:
+ return isinstance(other, ProtoPackageRemoved) and self.right == other.right
diff --git a/src/proto_range.py b/src/proto_range.py
index 2162f79..4f716c3 100644
--- a/src/proto_range.py
+++ b/src/proto_range.py
@@ -5,6 +5,11 @@
from src.proto_node import ParsedProtoNode, ProtoNode
+class ParsedProtoRangeNode(ParsedProtoNode):
+ node: "ProtoRange"
+ remaining_source: str
+
+
class ProtoRangeEnum(Enum):
MAX = "max"
@@ -35,7 +40,7 @@ def normalize(self) -> "ProtoRange":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoRangeNode"]:
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("-") and proto_source != "-":
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
@@ -53,7 +58,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
if proto_source.startswith("to "):
proto_source = proto_source[3:]
if proto_source.startswith("max"):
- return ParsedProtoNode(
+ return ParsedProtoRangeNode(
ProtoRange(min, ProtoRangeEnum.MAX),
proto_source[3:].strip(),
)
@@ -72,7 +77,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
max = match.node
proto_source = match.remaining_source
- return ParsedProtoNode(ProtoRange(min, max), proto_source.strip())
+ return ParsedProtoRangeNode(ProtoRange(min, max), proto_source.strip())
def serialize(self) -> str:
if self.max is not None:
diff --git a/src/proto_reserved.py b/src/proto_reserved.py
index 24b40f0..9a9c40f 100644
--- a/src/proto_reserved.py
+++ b/src/proto_reserved.py
@@ -49,11 +49,18 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoReserved":
# sort the ranges.
return ProtoReserved(
- sorted(self.ranges, key=lambda r: r.min),
- sorted(self.fields),
+ sorted(self.ranges, key=lambda r: int(r.min)),
+ sorted(self.fields, key=lambda f: str(f)),
self.quote_type,
)
+ @property
+ def min(self) -> str | int:
+ if self.ranges:
+ return int(min(self.ranges, key=lambda r: int(r.min)).min)
+ else:
+ return str(min(self.fields, key=lambda f: str(f)))
+
@classmethod
def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("reserved "):
@@ -74,10 +81,10 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
)
if proto_source[0] == ",":
proto_source = proto_source[1:].strip()
- match = ProtoRange.match(proto_source)
- if match is not None:
- ranges.append(match.node)
- proto_source = match.remaining_source
+ range_match = ProtoRange.match(proto_source)
+ if range_match is not None:
+ ranges.append(range_match.node)
+ proto_source = range_match.remaining_source
else:
# Maybe this is a field identifier.
quote_types = [
@@ -116,6 +123,7 @@ def serialize(self) -> str:
+ ", ".join(
f"{self.quote_type.value}{f.serialize()}{self.quote_type.value}"
for f in self.fields
+ if self.quote_type is not None
),
]
return " ".join(serialize_parts) + ";"
diff --git a/src/proto_service.py b/src/proto_service.py
index ec00cd3..76ec889 100644
--- a/src/proto_service.py
+++ b/src/proto_service.py
@@ -142,10 +142,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
proto_source = proto_source[1:].strip()
# Try to parse options.
- options = []
+ options: list[ProtoOption] = []
if proto_source.startswith("{"):
proto_source = proto_source[1:].strip()
- options = []
while proto_source:
# Remove empty statements.
if proto_source.startswith(";"):
@@ -232,12 +231,13 @@ def normalize(self) -> "ProtoService":
@staticmethod
def parse_partial_content(partial_service_content: str) -> ParsedProtoNode:
- for node_type in (
+ supported_types: list[type[ProtoNode]] = [
ProtoOption,
ProtoServiceRPC,
ProtoSingleLineComment,
ProtoMultiLineComment,
- ):
+ ]
+ for node_type in supported_types:
try:
match_result = node_type.match(partial_service_content)
except (ValueError, IndexError, TypeError):
diff --git a/src/proto_string_literal.py b/src/proto_string_literal.py
index 7336b0f..9ca0339 100644
--- a/src/proto_string_literal.py
+++ b/src/proto_string_literal.py
@@ -3,6 +3,11 @@
from src.proto_node import ParsedProtoNode, ProtoNode
+class ParsedProtoStringLiteralNode(ParsedProtoNode):
+ node: "ProtoStringLiteral"
+ remaining_source: str
+
+
class ProtoStringLiteral(ProtoNode):
QUOTES = ['"', "'"]
@@ -26,7 +31,7 @@ def normalize(self) -> "ProtoStringLiteral":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoStringLiteralNode"]:
if not any(proto_source.startswith(c) for c in ProtoStringLiteral.QUOTES):
return None
escaped = False
@@ -36,7 +41,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
escaped = True
continue
if c == starting_quote and not escaped:
- return ParsedProtoNode(
+ return ParsedProtoStringLiteralNode(
ProtoStringLiteral(proto_source[1 : i + 1], quote=starting_quote),
proto_source[i + 2 :].strip(),
)
diff --git a/src/proto_syntax.py b/src/proto_syntax.py
index 25109c7..0d1496a 100644
--- a/src/proto_syntax.py
+++ b/src/proto_syntax.py
@@ -5,6 +5,11 @@
from src.proto_string_literal import ProtoStringLiteral
+class ParsedProtoSyntaxNode(ParsedProtoNode):
+ node: "ProtoSyntax"
+ remaining_source: str
+
+
class ProtoSyntaxType(Enum):
PROTO2 = "proto2"
PROTO3 = "proto3"
@@ -23,14 +28,14 @@ def __str__(self) -> str:
def __repr__(self) -> str:
return str(self)
- def __dict__(self) -> dict:
+ def __dict__(self):
return {"syntax": self.syntax.serialize()}
def normalize(self) -> "ProtoSyntax":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(cls, proto_source: str) -> Optional["ParsedProtoSyntaxNode"]:
if not proto_source.startswith("syntax = "):
return None
proto_source = proto_source[9:]
@@ -46,7 +51,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
f"Proto has unknown syntax type: {match.node.value}, must be one of: {[proto_type.name for proto_type in ProtoSyntaxType]}"
)
- return ParsedProtoNode(
+ return ParsedProtoSyntaxNode(
ProtoSyntax(match.node),
match.remaining_source.strip(),
)
@@ -62,9 +67,13 @@ def diff(left: "ProtoSyntax", right: "ProtoSyntax") -> list["ProtoNodeDiff"]:
class ProtoSyntaxChanged(ProtoNodeDiff):
- def __init__(self, left: ProtoStringLiteral, right: ProtoStringLiteral):
+ def __init__(self, left: ProtoSyntax, right: ProtoSyntax):
self.left = left
self.right = right
- def __eq__(self, other: "ProtoSyntaxChanged") -> bool:
- return self.left == other.left and self.right == other.right
+ def __eq__(self, other: object) -> bool:
+ return (
+ isinstance(other, ProtoSyntaxChanged)
+ and self.left == other.left
+ and self.right == other.right
+ )
diff --git a/test/proto_message_test.py b/test/proto_message_test.py
index 19195a9..0812498 100644
--- a/test/proto_message_test.py
+++ b/test/proto_message_test.py
@@ -72,7 +72,7 @@ def test_message_all_features(self):
ProtoIdentifier("(foo.bar).baz"),
ProtoConstant(ProtoStringLiteral("bat")),
),
- ProtoMessage(
+ ProtoEnum(
ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
@@ -295,7 +295,7 @@ def test_message_nested_enum(self):
ProtoMessage(
ProtoIdentifier("FooMessage"),
[
- ProtoMessage(
+ ProtoEnum(
ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
From 0e0dd543df5be1db357478ca2842cdf7331387f8 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sat, 18 Feb 2023 22:40:31 -0500
Subject: [PATCH 11/35] [wip] start adding message field diffs (#66)
---
TODO.md | 1 +
src/parser.py | 6 +-
src/proto_bool.py | 15 +-
src/proto_comment.py | 19 +-
src/proto_constant.py | 34 +-
src/proto_enum.py | 51 ++-
src/proto_extend.py | 24 +-
src/proto_extensions.py | 13 +-
src/proto_float.py | 15 +-
src/proto_identifier.py | 26 +-
src/proto_import.py | 16 +-
src/proto_int.py | 13 +-
src/proto_message.py | 158 ++++++--
src/proto_message_field.py | 29 +-
src/proto_node.py | 7 +-
src/proto_option.py | 46 ++-
src/proto_package.py | 9 +-
src/proto_range.py | 30 +-
src/proto_reserved.py | 27 +-
src/proto_service.py | 50 ++-
src/proto_string_literal.py | 11 +-
src/proto_syntax.py | 11 +-
test/parser_test.py | 194 ++++++----
test/proto_bool_test.py | 20 +-
test/proto_comment_test.py | 28 +-
test/proto_constant_test.py | 155 ++++----
test/proto_enum_test.py | 548 ++++++++++++++++++----------
test/proto_extend_test.py | 32 +-
test/proto_extensions_test.py | 14 +-
test/proto_float_test.py | 64 ++--
test/proto_identifier_test.py | 93 ++---
test/proto_import_test.py | 74 ++--
test/proto_int_test.py | 24 +-
test/proto_message_field_test.py | 60 +--
test/proto_message_test.py | 583 +++++++++++++++++++-----------
test/proto_option_test.py | 389 +++++++++++---------
test/proto_package_test.py | 55 +--
test/proto_range_test.py | 32 +-
test/proto_reserved_test.py | 20 +-
test/proto_service_test.py | 197 ++++++----
test/proto_string_literal_test.py | 26 +-
test/proto_syntax_test.py | 64 ++--
42 files changed, 2079 insertions(+), 1204 deletions(-)
diff --git a/TODO.md b/TODO.md
index ca4a7e7..e738ea0 100644
--- a/TODO.md
+++ b/TODO.md
@@ -85,6 +85,7 @@
- [ ] Additions/removals
- [ ] Option changes
- [ ] Backwards-compatibility check
+ - [ ] __eq__ should enforce parent equality
- [ ] Scoping of diffs under containing objects
- [ ] Enum options under enums
- [ ] Enum value changes under enums
diff --git a/src/parser.py b/src/parser.py
index 75b9de9..62a4723 100644
--- a/src/parser.py
+++ b/src/parser.py
@@ -38,7 +38,7 @@ def parse_partial_content(partial_proto_content: str) -> ParsedProtoNode:
]
for node_type in node_types:
try:
- match_result = node_type.match(partial_proto_content)
+ match_result = node_type.match(None, partial_proto_content)
except (ValueError, IndexError, TypeError):
raise ParseError(
f"Could not parse proto content:\n{partial_proto_content}"
@@ -56,7 +56,7 @@ def parse_syntax_and_preceding_comments(
while True:
for node_type in [ProtoSingleLineComment, ProtoMultiLineComment]:
try:
- match_result = node_type.match(proto_content)
+ match_result = node_type.match(None, proto_content)
except (ValueError, IndexError, TypeError):
raise ParseError(f"Could not parse proto content:\n{proto_content}")
if match_result is not None:
@@ -68,7 +68,7 @@ def parse_syntax_and_preceding_comments(
# Next, parse syntax.
try:
- syntax_match = ProtoSyntax.match(proto_content.strip())
+ syntax_match = ProtoSyntax.match(None, proto_content.strip())
except (ValueError, IndexError, TypeError):
raise ParseError(f"Proto doesn't have parseable syntax:\n{proto_content}")
if syntax_match is None:
diff --git a/src/proto_bool.py b/src/proto_bool.py
index 4704aa1..879f0ff 100644
--- a/src/proto_bool.py
+++ b/src/proto_bool.py
@@ -10,7 +10,8 @@ class ParsedProtoBoolNode(ParsedProtoNode):
class ProtoBool(ProtoNode):
- def __init__(self, value: bool):
+ def __init__(self, parent: Optional[ProtoNode], value: bool):
+ super().__init__(parent)
self.value = value
def __bool__(self) -> bool:
@@ -29,15 +30,21 @@ def normalize(self) -> "ProtoBool":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoBoolNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoBoolNode"]:
if proto_source.startswith("true") and (
len(proto_source) == 4 or proto_source[4] not in ProtoFullIdentifier.ALL
):
- return ParsedProtoBoolNode(ProtoBool(True), proto_source[4:].strip())
+ return ParsedProtoBoolNode(
+ ProtoBool(parent, True), proto_source[4:].strip()
+ )
elif proto_source.startswith("false") and (
len(proto_source) == 5 or proto_source[5] not in ProtoFullIdentifier.ALL
):
- return ParsedProtoBoolNode(ProtoBool(False), proto_source[5:].strip())
+ return ParsedProtoBoolNode(
+ ProtoBool(parent, False), proto_source[5:].strip()
+ )
return None
def serialize(self) -> str:
diff --git a/src/proto_comment.py b/src/proto_comment.py
index 8d726ed..d3d6db7 100644
--- a/src/proto_comment.py
+++ b/src/proto_comment.py
@@ -10,7 +10,8 @@ class ParsedProtoCommentNode(ParsedProtoNode):
class ProtoComment(ProtoNode):
- def __init__(self, value: str):
+ def __init__(self, parent: Optional[ProtoNode], value: str):
+ super().__init__(parent)
self.value = value
def __eq__(self, other) -> bool:
@@ -26,7 +27,9 @@ def normalize(self) -> Optional["ProtoComment"]:
return None
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoCommentNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoCommentNode"]:
return None
def serialize(self) -> str:
@@ -43,7 +46,9 @@ def __str__(self) -> str:
return f""
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoSingleLineCommentNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoSingleLineCommentNode"]:
if not proto_source.startswith("//"):
return None
@@ -52,7 +57,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoSingleLineCommentNode"
if newline_pos == -1:
newline_pos = len(proto_source)
return ParsedProtoSingleLineCommentNode(
- ProtoSingleLineComment(proto_source[:newline_pos]),
+ ProtoSingleLineComment(parent, proto_source[:newline_pos]),
proto_source[newline_pos + 1 :],
)
@@ -70,7 +75,9 @@ def __str__(self) -> str:
return f""
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoMultiLineCommentNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoMultiLineCommentNode"]:
if not proto_source.startswith("/*"):
return None
@@ -79,7 +86,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoMultiLineCommentNode"]
if close_comment_pos == -1:
return None
return ParsedProtoMultiLineCommentNode(
- ProtoMultiLineComment(proto_source[:close_comment_pos]),
+ ProtoMultiLineComment(parent, proto_source[:close_comment_pos]),
proto_source[close_comment_pos + 2 :],
)
diff --git a/src/proto_constant.py b/src/proto_constant.py
index e95fda6..10cb623 100644
--- a/src/proto_constant.py
+++ b/src/proto_constant.py
@@ -20,9 +20,12 @@ class ParsedProtoConstantNode(ParsedProtoNode):
class ProtoConstant(ProtoNode):
def __init__(
self,
+ parent: Optional[ProtoNode],
value: ProtoConstantTypes,
):
+ super().__init__(parent)
self.value = value
+ self.value.parent = self
def __eq__(self, other) -> bool:
return self.value == other.value
@@ -37,51 +40,56 @@ def normalize(self) -> "ProtoConstant":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoConstantNode"]:
- match = ProtoBool.match(proto_source)
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoConstantNode"]:
+ match = ProtoBool.match(None, proto_source)
if match is not None:
+ proto_constant = ProtoConstant(parent, match.node)
return ParsedProtoConstantNode(
- ProtoConstant(match.node),
+ proto_constant,
match.remaining_source.strip(),
)
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("+") or proto_source.startswith("-"):
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- proto_int_match = ProtoInt.match(proto_source[1:])
+ proto_int_match = ProtoInt.match(None, proto_source[1:])
else:
- proto_int_match = ProtoInt.match(proto_source)
+ proto_int_match = ProtoInt.match(None, proto_source)
if proto_int_match is not None:
+ proto_constant = ProtoConstant(parent, proto_int_match.node)
proto_int_match.node.sign = sign
return ParsedProtoConstantNode(
- ProtoConstant(proto_int_match.node),
+ proto_constant,
proto_int_match.remaining_source.strip(),
)
float_sign = ProtoFloatSign.POSITIVE
if proto_source.startswith("+") or proto_source.startswith("-"):
float_sign = next(x for x in ProtoFloatSign if x.value == proto_source[0])
- float_match = ProtoFloat.match(proto_source[1:])
+ float_match = ProtoFloat.match(None, proto_source[1:])
else:
- float_match = ProtoFloat.match(proto_source)
+ float_match = ProtoFloat.match(None, proto_source)
if float_match is not None:
+ proto_constant = ProtoConstant(parent, float_match.node)
float_match.node.sign = float_sign
return ParsedProtoConstantNode(
- ProtoConstant(float_match.node),
+ proto_constant,
float_match.remaining_source.strip(),
)
- identifier_match = ProtoFullIdentifier.match(proto_source)
+ identifier_match = ProtoFullIdentifier.match(None, proto_source)
if identifier_match is not None:
return ParsedProtoConstantNode(
- ProtoConstant(identifier_match.node),
+ ProtoConstant(parent, identifier_match.node),
identifier_match.remaining_source.strip(),
)
- string_literal_match = ProtoStringLiteral.match(proto_source)
+ string_literal_match = ProtoStringLiteral.match(None, proto_source)
if string_literal_match is not None:
return ParsedProtoConstantNode(
- ProtoConstant(string_literal_match.node),
+ ProtoConstant(parent, string_literal_match.node),
string_literal_match.remaining_source.strip(),
)
diff --git a/src/proto_enum.py b/src/proto_enum.py
index e461efb..a5e1f47 100644
--- a/src/proto_enum.py
+++ b/src/proto_enum.py
@@ -22,13 +22,15 @@ def __str__(self) -> str:
return f"<{self.__class__.__name__} name={self.name}, value={self.value}>"
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoEnumValueOptionNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoEnumValueOptionNode"]:
test_source = "option " + proto_source.strip() + ";"
- match = ProtoOption.match(test_source)
+ match = ProtoOption.match(None, test_source)
if match is None:
return None
return ParsedProtoEnumValueOptionNode(
- cls(match.node.name, match.node.value),
+ cls(parent, match.node.name, match.node.value),
match.remaining_source.strip(),
)
@@ -44,17 +46,23 @@ class ParsedProtoEnumValueNode(ParsedProtoNode):
class ProtoEnumValue(ProtoNode):
def __init__(
self,
+ parent: Optional[ProtoNode],
identifier: ProtoIdentifier,
value: ProtoInt,
options: Optional[list[ProtoEnumValueOption]] = None,
):
+ super().__init__(parent)
self.identifier = identifier
+ self.identifier.parent = self
self.value = value
+ self.value.parent = self
if options is None:
self.options = []
else:
self.options = options
+ for option in self.options:
+ option.parent = self
def __eq__(self, other) -> bool:
return (
@@ -74,14 +82,17 @@ def __hash__(self) -> int:
def normalize(self) -> "ProtoEnumValue":
return ProtoEnumValue(
+ self.parent,
self.identifier,
self.value,
sorted(self.options, key=lambda o: str(o.name)),
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoEnumValueNode"]:
- match = ProtoIdentifier.match(proto_source)
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoEnumValueNode"]:
+ match = ProtoIdentifier.match(None, proto_source)
if match is None:
raise ValueError(f"Proto has invalid enum value name: {proto_source}")
@@ -98,9 +109,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoEnumValueNode"]:
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("-"):
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- int_match = ProtoInt.match(proto_source[1:])
+ int_match = ProtoInt.match(None, proto_source[1:])
else:
- int_match = ProtoInt.match(proto_source)
+ int_match = ProtoInt.match(None, proto_source)
if int_match is None:
raise ValueError(
f"Proto has invalid enum value, expecting int: {proto_source}"
@@ -120,7 +131,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoEnumValueNode"]:
)
for option_part in proto_source[:end_bracket].strip().split(","):
proto_enum_value_option_match = ProtoEnumValueOption.match(
- option_part.strip()
+ None, option_part.strip()
)
if proto_enum_value_option_match is None:
raise ValueError(
@@ -130,7 +141,8 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoEnumValueNode"]:
proto_source = proto_source[end_bracket + 1 :].strip()
return ParsedProtoEnumValueNode(
- ProtoEnumValue(enum_value_name, enum_value, options), proto_source.strip()
+ ProtoEnumValue(parent, enum_value_name, enum_value, options),
+ proto_source.strip(),
)
def serialize(self) -> str:
@@ -205,9 +217,15 @@ def diff_sets(
class ProtoEnum(ProtoNode):
- def __init__(self, name: ProtoIdentifier, nodes: list[ProtoNode]):
+ def __init__(
+ self, parent: Optional[ProtoNode], name: ProtoIdentifier, nodes: list[ProtoNode]
+ ):
+ super().__init__(parent)
self.name = name
+ self.name.parent = self
self.nodes = nodes
+ for option in self.options:
+ option.parent = self
def __eq__(self, other: object) -> bool:
return (
@@ -227,6 +245,7 @@ def normalize(self) -> "ProtoEnum":
lambda n1: not isinstance(n1, ProtoComment), self.nodes
)
return ProtoEnum(
+ self.parent,
self.name,
sorted(non_comment_nodes, key=lambda n: str(n.normalize())),
)
@@ -242,7 +261,7 @@ def parse_partial_content(partial_enum_content: str) -> ParsedProtoNode:
]
for node_type in supported_types:
try:
- match_result = node_type.match(partial_enum_content)
+ match_result = node_type.match(None, partial_enum_content)
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial enum content:\n{partial_enum_content}"
@@ -254,12 +273,14 @@ def parse_partial_content(partial_enum_content: str) -> ParsedProtoNode:
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("enum "):
return None
proto_source = proto_source[5:]
- match = ProtoIdentifier.match(proto_source)
+ match = ProtoIdentifier.match(None, proto_source)
if match is None:
raise ValueError(f"Proto has invalid enum name: {proto_source}")
@@ -287,7 +308,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
parsed_tree.append(match_result.node)
proto_source = match_result.remaining_source.strip()
- return ParsedProtoNode(ProtoEnum(enum_name, nodes=parsed_tree), proto_source)
+ return ParsedProtoNode(
+ ProtoEnum(parent, enum_name, nodes=parsed_tree), proto_source
+ )
@property
def options(self) -> list[ProtoOption]:
diff --git a/src/proto_extend.py b/src/proto_extend.py
index cb563a3..8585fdb 100644
--- a/src/proto_extend.py
+++ b/src/proto_extend.py
@@ -11,9 +11,18 @@
class ProtoExtend(ProtoNode):
- def __init__(self, name: ProtoEnumOrMessageIdentifier, nodes: list[ProtoNode]):
+ def __init__(
+ self,
+ parent: Optional[ProtoNode],
+ name: ProtoEnumOrMessageIdentifier,
+ nodes: list[ProtoNode],
+ ):
+ super().__init__(parent)
self.name = name
+ self.name.parent = self
self.nodes = nodes
+ for node in self.nodes:
+ node.parent = self
def __eq__(self, other) -> bool:
return self.name == other.name and self.nodes == other.nodes
@@ -29,6 +38,7 @@ def normalize(self) -> "ProtoExtend":
lambda n: not isinstance(n, ProtoComment), self.nodes
)
return ProtoExtend(
+ self.parent,
name=self.name,
nodes=sorted(non_comment_nodes, key=lambda f: str(f)),
)
@@ -42,7 +52,7 @@ def parse_partial_content(partial_content: str) -> ParsedProtoNode:
]
for node_type in supported_types:
try:
- match_result = node_type.match(partial_content)
+ match_result = node_type.match(None, partial_content)
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial extend content:\n{partial_content}"
@@ -52,12 +62,14 @@ def parse_partial_content(partial_content: str) -> ParsedProtoNode:
raise ValueError(f"Could not parse partial extend content:\n{partial_content}")
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("extend "):
return None
proto_source = proto_source[7:]
- match = ProtoEnumOrMessageIdentifier.match(proto_source)
+ match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
if match is None:
raise ValueError(f"Proto extend has invalid message name: {proto_source}")
@@ -85,7 +97,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
parsed_tree.append(match_result.node)
proto_source = match_result.remaining_source.strip()
- return ParsedProtoNode(ProtoExtend(name, nodes=parsed_tree), proto_source)
+ return ParsedProtoNode(
+ ProtoExtend(parent, name, nodes=parsed_tree), proto_source
+ )
def serialize(self) -> str:
serialize_parts = (
diff --git a/src/proto_extensions.py b/src/proto_extensions.py
index e4fb2f3..c8cf998 100644
--- a/src/proto_extensions.py
+++ b/src/proto_extensions.py
@@ -9,9 +9,13 @@
class ProtoExtensions(ProtoNode):
def __init__(
self,
+ parent: Optional[ProtoNode],
ranges: list[ProtoRange],
):
+ super().__init__(parent)
self.ranges = ranges
+ for range in self.ranges:
+ range.parent = self
def __eq__(self, other) -> bool:
return self.ranges == other.ranges
@@ -25,11 +29,14 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoExtensions":
# sort the ranges.
return ProtoExtensions(
+ self.parent,
sorted(self.ranges, key=lambda r: int(r.min)),
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("extensions "):
return None
@@ -46,13 +53,13 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
)
if proto_source[0] == ",":
proto_source = proto_source[1:].strip()
- match = ProtoRange.match(proto_source)
+ match = ProtoRange.match(None, proto_source)
if match is None:
return None
ranges.append(match.node)
proto_source = match.remaining_source
- return ParsedProtoNode(ProtoExtensions(ranges), proto_source.strip())
+ return ParsedProtoNode(ProtoExtensions(parent, ranges), proto_source.strip())
def serialize(self) -> str:
serialize_parts = ["extensions", ", ".join(r.serialize() for r in self.ranges)]
diff --git a/src/proto_float.py b/src/proto_float.py
index a139b11..d86b22d 100644
--- a/src/proto_float.py
+++ b/src/proto_float.py
@@ -22,7 +22,8 @@ class ProtoFloat(ProtoNode):
DECIMAL = DIGITS | set(".")
EXPONENTIAL = set("eE")
- def __init__(self, value: float, sign: ProtoFloatSign):
+ def __init__(self, parent: Optional[ProtoNode], value: float, sign: ProtoFloatSign):
+ super().__init__(parent)
self.value = value
self.sign = sign
@@ -43,7 +44,9 @@ def normalize(self) -> "ProtoFloat":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoFloatNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoFloatNode"]:
if proto_source.startswith("inf"):
proto_source = proto_source[3:]
if proto_source and proto_source[0] in ProtoIdentifier.ALL:
@@ -51,7 +54,8 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoFloatNode"]:
f"Proto has invalid float, invalid post-inf character: {proto_source}"
)
return ParsedProtoFloatNode(
- ProtoFloat(float("inf"), ProtoFloatSign.POSITIVE), proto_source.strip()
+ ProtoFloat(parent, float("inf"), ProtoFloatSign.POSITIVE),
+ proto_source.strip(),
)
if proto_source.startswith("nan"):
@@ -61,7 +65,8 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoFloatNode"]:
f"Proto has invalid float, invalid post-nan character: {proto_source}"
)
return ParsedProtoFloatNode(
- ProtoFloat(float("nan"), ProtoFloatSign.POSITIVE), proto_source.strip()
+ ProtoFloat(parent, float("nan"), ProtoFloatSign.POSITIVE),
+ proto_source.strip(),
)
if not proto_source[0] in ProtoFloat.DECIMAL:
@@ -113,7 +118,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoFloatNode"]:
proto_source = proto_source[i + 1 :]
return ParsedProtoFloatNode(
- ProtoFloat(base, ProtoFloatSign.POSITIVE), proto_source.strip()
+ ProtoFloat(parent, base, ProtoFloatSign.POSITIVE), proto_source.strip()
)
def serialize(self) -> str:
diff --git a/src/proto_identifier.py b/src/proto_identifier.py
index ee5368b..114c684 100644
--- a/src/proto_identifier.py
+++ b/src/proto_identifier.py
@@ -23,7 +23,8 @@ class ProtoIdentifier(ProtoNode):
STARTING = ALPHABETICAL | set("_")
ALL = STARTING | set("0123456789_")
- def __init__(self, identifier: str):
+ def __init__(self, parent: Optional[ProtoNode], identifier: str):
+ super().__init__(parent)
self.identifier = identifier
def __eq__(self, other) -> bool:
@@ -42,16 +43,18 @@ def normalize(self) -> "ProtoIdentifier":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoIdentifierNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoIdentifierNode"]:
if proto_source[0] not in ProtoIdentifier.STARTING:
return None
for i, c in enumerate(proto_source):
if c not in ProtoIdentifier.ALL:
return ParsedProtoIdentifierNode(
- ProtoIdentifier(proto_source[:i]), proto_source[i:]
+ ProtoIdentifier(parent, proto_source[:i]), proto_source[i:]
)
- return ParsedProtoIdentifierNode(ProtoIdentifier(proto_source), "")
+ return ParsedProtoIdentifierNode(ProtoIdentifier(parent, proto_source), "")
def serialize(self) -> str:
return self.identifier
@@ -62,7 +65,9 @@ class ProtoFullIdentifier(ProtoIdentifier):
ALL = ProtoIdentifier.ALL | set(".")
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoFullIdentifierNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoFullIdentifierNode"]:
if proto_source[0] not in ProtoFullIdentifier.STARTING:
return None
@@ -77,7 +82,8 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoFullIdentifierNode"]:
)
identifier_parts.append(proto_source[last_part_start:i])
return ParsedProtoFullIdentifierNode(
- ProtoFullIdentifier(".".join(identifier_parts)), proto_source[i:]
+ ProtoFullIdentifier(parent, ".".join(identifier_parts)),
+ proto_source[i:],
)
elif c == ".":
identifier_parts.append(proto_source[last_part_start:i])
@@ -90,7 +96,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoFullIdentifierNode"]:
)
identifier_parts.append(proto_source[last_part_start:])
return ParsedProtoFullIdentifierNode(
- ProtoFullIdentifier(".".join(identifier_parts)), ""
+ ProtoFullIdentifier(parent, ".".join(identifier_parts)), ""
)
@@ -100,17 +106,17 @@ class ProtoEnumOrMessageIdentifier(ProtoIdentifier):
@classmethod
def match(
- cls, proto_source: str
+ cls, parent: Optional[ProtoNode], proto_source: str
) -> Optional["ParsedProtoEnumOrMessageIdentifierNode"]:
if proto_source[0] == ".":
matched_source = proto_source[1:]
else:
matched_source = proto_source
- identifier_match = ProtoFullIdentifier.match(matched_source)
+ identifier_match = ProtoFullIdentifier.match(parent, matched_source)
if identifier_match is not None:
match = ParsedProtoEnumOrMessageIdentifierNode(
- ProtoEnumOrMessageIdentifier(identifier_match.node.identifier),
+ ProtoEnumOrMessageIdentifier(parent, identifier_match.node.identifier),
identifier_match.remaining_source,
)
diff --git a/src/proto_import.py b/src/proto_import.py
index dc67721..fdd0ba9 100644
--- a/src/proto_import.py
+++ b/src/proto_import.py
@@ -6,9 +6,15 @@
class ProtoImport(ProtoNode):
def __init__(
- self, path: ProtoStringLiteral, weak: bool = False, public: bool = False
+ self,
+ parent: Optional[ProtoNode],
+ path: ProtoStringLiteral,
+ weak: bool = False,
+ public: bool = False,
):
+ super().__init__(parent)
self.path = path
+ self.path.parent = self
self.weak = weak
self.public = public
@@ -36,7 +42,9 @@ def normalize(self) -> "ProtoImport":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("import "):
return None
proto_source = proto_source[7:]
@@ -53,7 +61,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
public = True
proto_source = proto_source[7:]
- match = ProtoStringLiteral.match(proto_source)
+ match = ProtoStringLiteral.match(None, proto_source)
if match is None:
raise ValueError(f"Proto has invalid import syntax: {proto_source}")
@@ -63,7 +71,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
)
return ParsedProtoNode(
- ProtoImport(match.node, weak=weak, public=public),
+ ProtoImport(parent, match.node, weak=weak, public=public),
match.remaining_source[1:].strip(),
)
diff --git a/src/proto_int.py b/src/proto_int.py
index 67aa7ba..480817f 100644
--- a/src/proto_int.py
+++ b/src/proto_int.py
@@ -20,7 +20,8 @@ class ProtoInt(ProtoNode):
DECIMAL = OCTAL | set("89")
HEX = DECIMAL | set("ABCDEFabcdef")
- def __init__(self, value: int, sign: ProtoIntSign):
+ def __init__(self, parent: Optional[ProtoNode], value: int, sign: ProtoIntSign):
+ super().__init__(parent)
self.value = value
self.sign = sign
@@ -43,7 +44,9 @@ def normalize(self) -> "ProtoInt":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoIntNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoIntNode"]:
if proto_source[0] not in ProtoInt.DECIMAL:
return None
@@ -64,7 +67,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoIntNode"]:
except ValueError:
raise ValueError(f"Proto has invalid hex: {proto_source}")
return ParsedProtoIntNode(
- ProtoInt(value, ProtoIntSign.POSITIVE),
+ ProtoInt(parent, value, ProtoIntSign.POSITIVE),
proto_source[i + 1 :].strip(),
)
else:
@@ -80,7 +83,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoIntNode"]:
except ValueError:
raise ValueError(f"Proto has invalid octal: {proto_source}")
return ParsedProtoIntNode(
- ProtoInt(value, ProtoIntSign.POSITIVE),
+ ProtoInt(parent, value, ProtoIntSign.POSITIVE),
proto_source[i + 1 :].strip(),
)
else:
@@ -97,7 +100,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoIntNode"]:
return None
return ParsedProtoIntNode(
- ProtoInt(value, ProtoIntSign.POSITIVE),
+ ProtoInt(parent, value, ProtoIntSign.POSITIVE),
proto_source[i + 1 :].strip(),
)
diff --git a/src/proto_message.py b/src/proto_message.py
index 191e127..bf82578 100644
--- a/src/proto_message.py
+++ b/src/proto_message.py
@@ -11,11 +11,7 @@
from src.proto_enum import ProtoEnum
from src.proto_extend import ProtoExtend
from src.proto_extensions import ProtoExtensions
-from src.proto_identifier import (
- ProtoEnumOrMessageIdentifier,
- ProtoFullIdentifier,
- ProtoIdentifier,
-)
+from src.proto_identifier import ProtoEnumOrMessageIdentifier, ProtoIdentifier
from src.proto_int import ProtoInt
from src.proto_message_field import (
ParsedProtoMessageFieldNode,
@@ -44,9 +40,18 @@ class ParsedProtoOneOfNode(ParsedProtoNode):
class ProtoOneOf(ProtoNode):
- def __init__(self, name: ProtoIdentifier, nodes: Sequence[ProtoOneOfNodeTypes]):
+ def __init__(
+ self,
+ parent: Optional[ProtoNode],
+ name: ProtoIdentifier,
+ nodes: Sequence[ProtoOneOfNodeTypes],
+ ):
+ super().__init__(parent)
self.name = name
+ self.name.parent = self
self.nodes = nodes
+ for node in self.nodes:
+ node.parent = self
def __eq__(self, other) -> bool:
return self.name == other.name and self.nodes == other.nodes
@@ -82,7 +87,8 @@ def normalize(self) -> "ProtoOneOf":
) + sorted(fields, key=lambda f: int(f.number))
return ProtoOneOf(
- self.name,
+ parent=self.parent,
+ name=self.name,
nodes=sorted_nodes_for_normalizing,
)
@@ -96,7 +102,7 @@ def parse_partial_content(partial_oneof_content: str) -> ProtoParsedOneOfNodeTyp
]
for node_type in supported_types:
try:
- match_result = node_type.match(partial_oneof_content)
+ match_result = node_type.match(None, partial_oneof_content)
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial oneof content:\n{partial_oneof_content}"
@@ -108,13 +114,15 @@ def parse_partial_content(partial_oneof_content: str) -> ProtoParsedOneOfNodeTyp
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoOneOfNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoOneOfNode"]:
if not proto_source.startswith("oneof "):
return None
proto_source = proto_source[6:].strip()
- match = ProtoIdentifier.match(proto_source)
+ match = ProtoIdentifier.match(None, proto_source)
if match is None:
raise ValueError(
f"Proto has invalid syntax, expecting identifier for oneof: {proto_source}"
@@ -145,7 +153,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoOneOfNode"]:
proto_source = match_result.remaining_source.strip()
return ParsedProtoOneOfNode(
- ProtoOneOf(oneof_name, nodes=parsed_tree), proto_source
+ ProtoOneOf(parent, oneof_name, nodes=parsed_tree), proto_source
)
@property
@@ -182,6 +190,7 @@ class ProtoMapKeyTypesEnum(Enum):
class ProtoMap(ProtoNode):
def __init__(
self,
+ parent: Optional[ProtoNode],
key_type: ProtoMapKeyTypesEnum,
value_type: ProtoMapValueTypesEnum,
name: ProtoIdentifier,
@@ -189,15 +198,22 @@ def __init__(
enum_or_message_type_name: Optional[ProtoEnumOrMessageIdentifier] = None,
options: Optional[list[ProtoMessageFieldOption]] = None,
):
+ super().__init__(parent)
self.key_type = key_type
self.value_type = value_type
self.name = name
+ self.name.parent = self
self.number = number
+ self.number.parent = self
self.enum_or_message_type_name = enum_or_message_type_name
+ if self.enum_or_message_type_name is not None:
+ self.enum_or_message_type_name.parent = self
if options is None:
options = []
self.options = options
+ for option in self.options:
+ option.parent = self
def __eq__(self, other) -> bool:
return (
@@ -217,6 +233,7 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoMap":
return ProtoMap(
+ parent=self.parent,
key_type=self.key_type,
value_type=self.value_type,
name=self.name,
@@ -226,7 +243,9 @@ def normalize(self) -> "ProtoMap":
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if proto_source.startswith("map "):
proto_source = proto_source[4:].strip()
elif proto_source.startswith("map<"):
@@ -263,7 +282,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
enum_or_message_type_name = None
if value_type is None:
# See if this is an enum or message type.
- match = ProtoEnumOrMessageIdentifier.match(proto_source)
+ match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
if match is None:
return None
value_type = ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE
@@ -275,7 +294,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
proto_source = proto_source[1:].strip()
# Try to match the map field's name.
- identifier_match = ProtoIdentifier.match(proto_source)
+ identifier_match = ProtoIdentifier.match(None, proto_source)
if identifier_match is None:
return None
name = identifier_match.node
@@ -286,7 +305,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
proto_source = proto_source[1:].strip()
# Try to match the map field number.
- int_match = ProtoInt.match(proto_source)
+ int_match = ProtoInt.match(None, proto_source)
if int_match is None:
return None
number = int_match.node
@@ -303,7 +322,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
)
for option_part in proto_source[:end_bracket].strip().split(","):
message_field_option_match = ProtoMessageFieldOption.match(
- option_part.strip()
+ None, option_part.strip()
)
if message_field_option_match is None:
raise ValueError(
@@ -319,7 +338,13 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
return ParsedProtoNode(
ProtoMap(
- key_type, value_type, name, number, enum_or_message_type_name, options
+ parent,
+ key_type,
+ value_type,
+ name,
+ number,
+ enum_or_message_type_name,
+ options,
),
proto_source[1:].strip(),
)
@@ -354,11 +379,85 @@ def serialize(self) -> str:
return " ".join(serialized_parts) + ";"
+ @staticmethod
+ def diff(
+ parent: Optional[ProtoNode], left: "ProtoMap", right: "ProtoMap"
+ ) -> list["ProtoNodeDiff"]:
+ if left is None and right is not None:
+ return [ProtoMapAdded(parent, right)]
+ elif left is not None and right is None:
+ return [ProtoMapRemoved(parent, left)]
+ elif left is None and right is None:
+ return []
+ elif left.name != right.name:
+ return []
+ elif left == right:
+ return []
+ diffs: list["ProtoNodeDiff"] = []
+ return diffs
+
+ @staticmethod
+ def diff_sets(
+ parent: Optional[ProtoNode], left: list["ProtoMap"], right: list["ProtoMap"]
+ ) -> Sequence["ProtoNodeDiff"]:
+ diffs: list[ProtoNodeDiff] = []
+ left_names = set(o.name.identifier for o in left)
+ right_names = set(o.name.identifier for o in right)
+ for name in left_names - right_names:
+ diffs.append(
+ ProtoMapAdded(
+ parent, next(i for i in left if i.name.identifier == name)
+ )
+ )
+ for name in right_names - left_names:
+ diffs.append(
+ ProtoMapRemoved(
+ parent, next(i for i in right if i.name.identifier == name)
+ )
+ )
+ for name in left_names & right_names:
+ left_enum = next(i for i in left if i.name.identifier == name)
+ right_enum = next(i for i in right if i.name.identifier == name)
+ diffs.extend(ProtoMap.diff(parent, left_enum, right_enum))
+
+ return diffs
+
+
+class ProtoMapDiff(ProtoNodeDiff):
+ def __init__(self, parent: Optional[ProtoNode], map: ProtoMap):
+ self.parent = parent
+ self.map = map
+
+ def __eq__(self, other: object) -> bool:
+ return isinstance(other, ProtoMapDiff) and self.map == other.map
+
+ def __str__(self) -> str:
+ return f"<{self.__class__.__name__} parent={self.parent} map={self.map}>"
+
+
+class ProtoMapAdded(ProtoMapDiff):
+ def __eq__(self, other: object) -> bool:
+ return super().__eq__(other) and isinstance(other, ProtoMapAdded)
+
+
+class ProtoMapRemoved(ProtoMapDiff):
+ def __eq__(self, other: object) -> bool:
+ return super().__eq__(other) and isinstance(other, ProtoMapRemoved)
+
class ProtoMessage(ProtoNode):
- def __init__(self, name: ProtoIdentifier, nodes: Sequence[ProtoNode]):
+ def __init__(
+ self,
+ parent: Optional[ProtoNode],
+ name: ProtoIdentifier,
+ nodes: Sequence[ProtoNode],
+ ):
+ super().__init__(parent)
self.name = name
+ self.name.parent = self
self.nodes = nodes
+ for node in self.nodes:
+ node.parent = self
def __eq__(self, other) -> bool:
return self.name == other.name and self.nodes == other.nodes
@@ -408,6 +507,7 @@ def normalize(self) -> "ProtoMessage":
)
return ProtoMessage(
+ parent=self.parent,
name=self.name,
nodes=sorted_nodes_for_normalizing,
)
@@ -429,7 +529,7 @@ def parse_partial_content(partial_message_content: str) -> ParsedProtoNode:
]
for node_type in supported_types:
try:
- match_result = node_type.match(partial_message_content)
+ match_result = node_type.match(None, partial_message_content)
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial message content:\n{partial_message_content}"
@@ -441,12 +541,14 @@ def parse_partial_content(partial_message_content: str) -> ParsedProtoNode:
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("message "):
return None
proto_source = proto_source[8:]
- match = ProtoIdentifier.match(proto_source)
+ match = ProtoIdentifier.match(None, proto_source)
if match is None:
raise ValueError(f"Proto has invalid message name: {proto_source}")
@@ -474,12 +576,18 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
parsed_tree.append(match_result.node)
proto_source = match_result.remaining_source.strip()
- return ParsedProtoNode(ProtoMessage(enum_name, nodes=parsed_tree), proto_source)
+ return ParsedProtoNode(
+ ProtoMessage(parent, enum_name, nodes=parsed_tree), proto_source
+ )
@property
def options(self) -> list[ProtoOption]:
return [node for node in self.nodes if isinstance(node, ProtoOption)]
+ @property
+ def maps(self) -> list[ProtoMap]:
+ return [node for node in self.nodes if isinstance(node, ProtoMap)]
+
def serialize(self) -> str:
serialize_parts = (
[f"message {self.name.serialize()} {{"]
@@ -500,9 +608,11 @@ def diff(left: "ProtoMessage", right: "ProtoMessage") -> Sequence["ProtoNodeDiff
return []
elif left == right:
return []
- diffs = []
+ diffs: list[ProtoNodeDiff] = []
diffs.extend(ProtoOption.diff_sets(left.options, right.options))
- # diffs.extend(ProtoMessageValue.diff_sets(left, left.values, right.values))
+ # diffs.extend(ProtoOneOf.diff_sets(left, left.oneofs, right.oneofs))
+ diffs.extend(ProtoMap.diff_sets(left, left.maps, right.maps))
+ # diffs.extend(ProtoMessageField.diff_sets(left, left.message_fields, right.message_fields))
return diffs
@staticmethod
diff --git a/src/proto_message_field.py b/src/proto_message_field.py
index 97f75ce..390cef8 100644
--- a/src/proto_message_field.py
+++ b/src/proto_message_field.py
@@ -14,10 +14,13 @@ class ParsedProtoMessageFieldOptionNode(ParsedProtoEnumValueOptionNode):
class ProtoMessageFieldOption(ProtoEnumValueOption):
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoMessageFieldOptionNode"]:
- match = super().match(proto_source)
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoMessageFieldOptionNode"]:
+ match = super().match(parent, proto_source)
if match is None:
return None
+
return ParsedProtoMessageFieldOptionNode(
match.node,
match.remaining_source.strip(),
@@ -51,6 +54,7 @@ class ParsedProtoMessageFieldNode(ParsedProtoNode):
class ProtoMessageField(ProtoNode):
def __init__(
self,
+ parent: Optional[ProtoNode],
type: ProtoMessageFieldTypesEnum,
name: ProtoIdentifier,
number: ProtoInt,
@@ -59,9 +63,12 @@ def __init__(
enum_or_message_type_name: Optional[ProtoEnumOrMessageIdentifier] = None,
options: Optional[list[ProtoMessageFieldOption]] = None,
):
+ super().__init__(parent)
self.type = type
self.name = name
+ self.name.parent = self
self.number = number
+ self.number.parent = self
# Only allow one of repeated or optional to be true.
if repeated and optional:
@@ -72,10 +79,14 @@ def __init__(
self.repeated = repeated
self.optional = optional
self.enum_or_message_type_name = enum_or_message_type_name
+ if self.enum_or_message_type_name is not None:
+ self.enum_or_message_type_name.parent = self
if options is None:
options = []
self.options = options
+ for option in self.options:
+ option.parent = self
def __eq__(self, other) -> bool:
return (
@@ -96,6 +107,7 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoMessageField":
return ProtoMessageField(
+ parent=self.parent,
type=self.type,
name=self.name,
number=self.number,
@@ -106,7 +118,9 @@ def normalize(self) -> "ProtoMessageField":
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoMessageFieldNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoMessageFieldNode"]:
# First, try to match the optional repeated.
repeated = False
if proto_source.startswith("repeated "):
@@ -136,7 +150,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoMessageFieldNode"]:
enum_or_message_type_name = None
if matched_type is None:
# See if this is an enum or message type.
- match = ProtoEnumOrMessageIdentifier.match(proto_source)
+ match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
if match is None:
return None
matched_type = ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE
@@ -144,7 +158,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoMessageFieldNode"]:
proto_source = match.remaining_source.strip()
# Match the field name.
- identifier_match = ProtoIdentifier.match(proto_source)
+ identifier_match = ProtoIdentifier.match(None, proto_source)
if identifier_match is None:
return None
name = identifier_match.node
@@ -155,7 +169,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoMessageFieldNode"]:
proto_source = proto_source[2:].strip()
# Match the field number.
- int_match = ProtoInt.match(proto_source)
+ int_match = ProtoInt.match(None, proto_source)
if int_match is None:
return None
number = int_match.node
@@ -171,7 +185,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoMessageFieldNode"]:
)
for option_part in proto_source[:end_bracket].strip().split(","):
message_field_option_match = ProtoMessageFieldOption.match(
- option_part.strip()
+ None, option_part.strip()
)
if message_field_option_match is None:
raise ValueError(
@@ -187,6 +201,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoMessageFieldNode"]:
return ParsedProtoMessageFieldNode(
ProtoMessageField(
+ parent,
matched_type,
name,
number,
diff --git a/src/proto_node.py b/src/proto_node.py
index 37c36e8..8d10bb4 100644
--- a/src/proto_node.py
+++ b/src/proto_node.py
@@ -5,9 +5,14 @@
class ProtoNode(abc.ABC):
@classmethod
@abc.abstractmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional["ProtoNode"], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
raise NotImplementedError
+ def __init__(self, parent: Optional["ProtoNode"]):
+ self.parent = parent
+
@abc.abstractmethod
def serialize(self) -> str:
raise NotImplementedError
diff --git a/src/proto_option.py b/src/proto_option.py
index a780351..312dcac 100644
--- a/src/proto_option.py
+++ b/src/proto_option.py
@@ -15,9 +15,14 @@ class ParsedProtoOptionNode(ParsedProtoNode):
class ProtoOption(ProtoNode):
- def __init__(self, name: ProtoIdentifier, value: ProtoConstant):
+ def __init__(
+ self, parent: Optional[ProtoNode], name: ProtoIdentifier, value: ProtoConstant
+ ):
+ super().__init__(parent)
self.name = name
+ self.name.parent = self
self.value = value
+ self.value.parent = self
def __eq__(self, other) -> bool:
return self.name == other.name and self.value == other.value
@@ -35,7 +40,9 @@ def normalize(self) -> "ProtoOption":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoOptionNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoOptionNode"]:
if not proto_source.startswith("option "):
return None
proto_source = proto_source[7:]
@@ -43,10 +50,10 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoOptionNode"]:
name_parts = []
if proto_source.startswith("("):
proto_source = proto_source[1:]
- match = ProtoFullIdentifier.match(proto_source)
+ match = ProtoFullIdentifier.match(None, proto_source)
if match is None or not match.remaining_source.startswith(")"):
# This might be a regular identifier.
- identifier_match = ProtoIdentifier.match(proto_source)
+ identifier_match = ProtoIdentifier.match(None, proto_source)
if (
not identifier_match
or not identifier_match.remaining_source.startswith(")")
@@ -55,17 +62,19 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoOptionNode"]:
f"Proto has invalid option when expecting ): {proto_source}"
)
name_parts.append(
- ProtoIdentifier(f"({identifier_match.node.identifier})")
+ ProtoIdentifier(None, f"({identifier_match.node.identifier})")
)
proto_source = identifier_match.remaining_source[1:]
else:
- name_parts.append(ProtoFullIdentifier(f"({match.node.identifier})"))
+ name_parts.append(
+ ProtoFullIdentifier(None, f"({match.node.identifier})")
+ )
proto_source = match.remaining_source[1:]
while True:
- identifier_match = ProtoEnumOrMessageIdentifier.match(proto_source)
+ identifier_match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
if identifier_match is None:
- identifier_match = ProtoIdentifier.match(proto_source)
+ identifier_match = ProtoIdentifier.match(None, proto_source)
if identifier_match is None:
break
name_parts.append(identifier_match.node)
@@ -77,7 +86,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoOptionNode"]:
f"Proto has invalid option when expecting =: {proto_source}"
)
proto_source = proto_source[1:].strip()
- constant_match = ProtoConstant.match(proto_source)
+ constant_match = ProtoConstant.match(None, proto_source)
if constant_match is None:
raise ValueError(
f"Proto has invalid option when expecting constant: {proto_source}"
@@ -91,15 +100,22 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoOptionNode"]:
identifier: ProtoFullIdentifier | ProtoIdentifier
if len(name_parts) > 1:
- identifier = ProtoFullIdentifier("".join(x.identifier for x in name_parts))
+ identifier = ProtoFullIdentifier(
+ None, "".join(x.identifier for x in name_parts)
+ )
else:
- identifier = ProtoIdentifier(name_parts[0].identifier)
+ identifier = ProtoIdentifier(None, name_parts[0].identifier)
+
+ proto_option = ProtoOption(
+ parent,
+ name=identifier,
+ value=constant_match.node,
+ )
+ identifier.parent = proto_option
+ constant_match.node.parent = proto_option
return ParsedProtoOptionNode(
- ProtoOption(
- name=identifier,
- value=constant_match.node,
- ),
+ proto_option,
proto_source[1:],
)
diff --git a/src/proto_package.py b/src/proto_package.py
index 7559cd6..d6d714a 100644
--- a/src/proto_package.py
+++ b/src/proto_package.py
@@ -4,7 +4,8 @@
class ProtoPackage(ProtoNode):
- def __init__(self, package: str):
+ def __init__(self, parent: Optional[ProtoNode], package: str):
+ super().__init__(parent)
self.package = package
def __eq__(self, other) -> bool:
@@ -20,7 +21,9 @@ def normalize(self) -> "ProtoPackage":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("package"):
return None
@@ -44,7 +47,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
if package.startswith(".") or package.endswith("."):
raise ValueError(f"Proto has invalid package: {package}")
- return ParsedProtoNode(ProtoPackage(package), proto_source.strip())
+ return ParsedProtoNode(ProtoPackage(parent, package), proto_source.strip())
def serialize(self) -> str:
return f"package {self.package};"
diff --git a/src/proto_range.py b/src/proto_range.py
index 4f716c3..b55b279 100644
--- a/src/proto_range.py
+++ b/src/proto_range.py
@@ -15,7 +15,13 @@ class ProtoRangeEnum(Enum):
class ProtoRange(ProtoNode):
- def __init__(self, min: ProtoInt, max: Optional[ProtoInt | ProtoRangeEnum] = None):
+ def __init__(
+ self,
+ parent: Optional[ProtoNode],
+ min: ProtoInt,
+ max: Optional[ProtoInt | ProtoRangeEnum] = None,
+ ):
+ super().__init__(parent)
self.min = min
if (
@@ -40,13 +46,15 @@ def normalize(self) -> "ProtoRange":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoRangeNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoRangeNode"]:
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("-") and proto_source != "-":
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- match = ProtoInt.match(proto_source[1:])
+ match = ProtoInt.match(None, proto_source[1:])
else:
- match = ProtoInt.match(proto_source)
+ match = ProtoInt.match(None, proto_source)
if match is None:
return None
@@ -58,17 +66,19 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoRangeNode"]:
if proto_source.startswith("to "):
proto_source = proto_source[3:]
if proto_source.startswith("max"):
+ proto_range = ProtoRange(parent, min, ProtoRangeEnum.MAX)
+ min.parent = proto_range
return ParsedProtoRangeNode(
- ProtoRange(min, ProtoRangeEnum.MAX),
+ proto_range,
proto_source[3:].strip(),
)
else:
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("-"):
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- match = ProtoInt.match(proto_source[1:])
+ match = ProtoInt.match(None, proto_source[1:])
else:
- match = ProtoInt.match(proto_source)
+ match = ProtoInt.match(None, proto_source)
if match is None:
raise ValueError(
f"Proto source has invalid range, expecting int for max: {proto_source}"
@@ -77,7 +87,11 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoRangeNode"]:
max = match.node
proto_source = match.remaining_source
- return ParsedProtoRangeNode(ProtoRange(min, max), proto_source.strip())
+ proto_range = ProtoRange(parent, min, max)
+ min.parent = proto_range
+ if isinstance(max, ProtoNode):
+ max.parent = proto_range
+ return ParsedProtoRangeNode(proto_range, proto_source.strip())
def serialize(self) -> str:
if self.max is not None:
diff --git a/src/proto_reserved.py b/src/proto_reserved.py
index 9a9c40f..06b146b 100644
--- a/src/proto_reserved.py
+++ b/src/proto_reserved.py
@@ -14,12 +14,14 @@ class ProtoReservedFieldQuoteEnum(Enum):
class ProtoReserved(ProtoNode):
def __init__(
self,
+ parent: Optional[ProtoNode],
ranges: Optional[list[ProtoRange]] = None,
fields: Optional[list[ProtoIdentifier]] = None,
quote_type: Optional[
ProtoReservedFieldQuoteEnum
] = ProtoReservedFieldQuoteEnum.DOUBLE,
):
+ super().__init__(parent)
if (not ranges and not fields) or (ranges and fields):
raise ValueError(
"Exactly one of ranges or fields must be set in a ProtoReserved"
@@ -30,11 +32,17 @@ def __init__(
if quote_type is None:
raise ValueError("Quote type must be specified when reserving fields")
+ self.ranges = ranges
+ for range in self.ranges:
+ range.parent = self
+
if fields is None:
fields = []
- self.ranges = ranges
self.fields = fields
+ for field in self.fields:
+ field.parent = self
+
self.quote_type = quote_type
def __eq__(self, other) -> bool:
@@ -49,9 +57,10 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoReserved":
# sort the ranges.
return ProtoReserved(
- sorted(self.ranges, key=lambda r: int(r.min)),
- sorted(self.fields, key=lambda f: str(f)),
- self.quote_type,
+ parent=self.parent,
+ ranges=sorted(self.ranges, key=lambda r: int(r.min)),
+ fields=sorted(self.fields, key=lambda f: str(f)),
+ quote_type=self.quote_type,
)
@property
@@ -62,7 +71,9 @@ def min(self) -> str | int:
return str(min(self.fields, key=lambda f: str(f)))
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("reserved "):
return None
@@ -81,7 +92,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
)
if proto_source[0] == ",":
proto_source = proto_source[1:].strip()
- range_match = ProtoRange.match(proto_source)
+ range_match = ProtoRange.match(None, proto_source)
if range_match is not None:
ranges.append(range_match.node)
proto_source = range_match.remaining_source
@@ -98,7 +109,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
)
quote_type = quote_types[0]
proto_source = proto_source[1:]
- match = ProtoIdentifier.match(proto_source)
+ match = ProtoIdentifier.match(None, proto_source)
if match is None:
raise ValueError(
f"Proto source has invalid reserved syntax, expecting field identifier: {proto_source}"
@@ -113,7 +124,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
proto_source = proto_source[1:].strip()
return ParsedProtoNode(
- ProtoReserved(ranges, fields, quote_type), proto_source.strip()
+ ProtoReserved(parent, ranges, fields, quote_type), proto_source.strip()
)
def serialize(self) -> str:
diff --git a/src/proto_service.py b/src/proto_service.py
index 76ec889..8ca62d4 100644
--- a/src/proto_service.py
+++ b/src/proto_service.py
@@ -13,6 +13,7 @@
class ProtoServiceRPC(ProtoNode):
def __init__(
self,
+ parent: Optional[ProtoNode],
name: ProtoIdentifier,
request_type: ProtoEnumOrMessageIdentifier,
response_type: ProtoEnumOrMessageIdentifier,
@@ -20,15 +21,21 @@ def __init__(
response_stream: bool = False,
options: Optional[list[ProtoOption]] = None,
):
+ super().__init__(parent)
self.name = name
+ self.name.parent = self
self.request_type = request_type
+ self.request_type.parent = self
self.response_type = response_type
+ self.response_type.parent = self
self.request_stream = request_stream
self.response_stream = response_stream
if options is None:
options = []
self.options = options
+ for option in self.options:
+ option.parent = self
def __eq__(self, other) -> bool:
return (
@@ -48,6 +55,7 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoServiceRPC":
return ProtoServiceRPC(
+ parent=self.parent,
name=self.name,
request_type=self.request_type,
response_type=self.response_type,
@@ -57,13 +65,15 @@ def normalize(self) -> "ProtoServiceRPC":
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("rpc "):
return None
proto_source = proto_source[4:].strip()
# Match the RPC name.
- name_match = ProtoIdentifier.match(proto_source)
+ name_match = ProtoIdentifier.match(None, proto_source)
if name_match is None:
return None
name = name_match.node
@@ -74,7 +84,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
proto_source = proto_source[1:].strip()
# Try to parse the request type.
- stream_or_request_name_match = ProtoEnumOrMessageIdentifier.match(proto_source)
+ stream_or_request_name_match = ProtoEnumOrMessageIdentifier.match(
+ None, proto_source
+ )
if stream_or_request_name_match is None:
return None
@@ -85,7 +97,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
elif stream_or_request_name_match.node.identifier == "stream":
# Try matching the request name.
potential_request_name_match = ProtoEnumOrMessageIdentifier.match(
- stream_or_request_name_match.remaining_source.strip()
+ None, stream_or_request_name_match.remaining_source.strip()
)
if potential_request_name_match is None:
# No further name.
@@ -112,7 +124,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
proto_source = proto_source[1:].strip()
# Try to parse the response type.
- stream_or_response_name_match = ProtoEnumOrMessageIdentifier.match(proto_source)
+ stream_or_response_name_match = ProtoEnumOrMessageIdentifier.match(
+ None, proto_source
+ )
if stream_or_response_name_match is None:
return None
@@ -123,7 +137,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
elif stream_or_response_name_match.node.identifier == "stream":
# Try matching the response name.
potential_response_name_match = ProtoEnumOrMessageIdentifier.match(
- stream_or_response_name_match.remaining_source.strip()
+ None, stream_or_response_name_match.remaining_source.strip()
)
if potential_response_name_match is None:
# No further name.
@@ -155,7 +169,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
proto_source = proto_source[1:].strip()
break
- option_match = ProtoOption.match(proto_source)
+ option_match = ProtoOption.match(None, proto_source)
if option_match is None:
return None
options.append(option_match.node)
@@ -167,6 +181,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
return ParsedProtoNode(
ProtoServiceRPC(
+ parent,
name,
request_name,
response_name,
@@ -207,9 +222,15 @@ def serialize(self) -> str:
class ProtoService(ProtoNode):
- def __init__(self, name: ProtoIdentifier, nodes: list[ProtoNode]):
+ def __init__(
+ self, parent: Optional[ProtoNode], name: ProtoIdentifier, nodes: list[ProtoNode]
+ ):
+ super().__init__(parent)
self.name = name
+ self.name.parent = self
self.nodes = nodes
+ for node in self.nodes:
+ node.parent = self
def __eq__(self, other) -> bool:
return self.name == other.name and self.nodes == other.nodes
@@ -225,6 +246,7 @@ def normalize(self) -> "ProtoService":
lambda n: not isinstance(n, ProtoComment), self.nodes
)
return ProtoService(
+ parent=self.parent,
name=self.name,
nodes=sorted(non_comment_nodes, key=lambda n: str(n.normalize())),
)
@@ -239,7 +261,7 @@ def parse_partial_content(partial_service_content: str) -> ParsedProtoNode:
]
for node_type in supported_types:
try:
- match_result = node_type.match(partial_service_content)
+ match_result = node_type.match(None, partial_service_content)
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial service content:\n{partial_service_content}"
@@ -251,12 +273,14 @@ def parse_partial_content(partial_service_content: str) -> ParsedProtoNode:
)
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("service "):
return None
proto_source = proto_source[8:]
- match = ProtoIdentifier.match(proto_source)
+ match = ProtoIdentifier.match(None, proto_source)
if match is None:
raise ValueError(f"Proto has invalid service name: {proto_source}")
@@ -284,7 +308,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoNode"]:
parsed_tree.append(match_result.node)
proto_source = match_result.remaining_source.strip()
- return ParsedProtoNode(ProtoService(enum_name, nodes=parsed_tree), proto_source)
+ return ParsedProtoNode(
+ ProtoService(parent, enum_name, nodes=parsed_tree), proto_source
+ )
@property
def options(self) -> list[ProtoOption]:
diff --git a/src/proto_string_literal.py b/src/proto_string_literal.py
index 9ca0339..1d98b57 100644
--- a/src/proto_string_literal.py
+++ b/src/proto_string_literal.py
@@ -11,7 +11,8 @@ class ParsedProtoStringLiteralNode(ParsedProtoNode):
class ProtoStringLiteral(ProtoNode):
QUOTES = ['"', "'"]
- def __init__(self, val: str, quote: str = QUOTES[0]):
+ def __init__(self, parent: Optional[ProtoNode], val: str, quote: str = QUOTES[0]):
+ super().__init__(parent)
self.value = val
self.quote = quote
@@ -31,7 +32,9 @@ def normalize(self) -> "ProtoStringLiteral":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoStringLiteralNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoStringLiteralNode"]:
if not any(proto_source.startswith(c) for c in ProtoStringLiteral.QUOTES):
return None
escaped = False
@@ -42,7 +45,9 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoStringLiteralNode"]:
continue
if c == starting_quote and not escaped:
return ParsedProtoStringLiteralNode(
- ProtoStringLiteral(proto_source[1 : i + 1], quote=starting_quote),
+ ProtoStringLiteral(
+ parent, proto_source[1 : i + 1], quote=starting_quote
+ ),
proto_source[i + 2 :].strip(),
)
escaped = False
diff --git a/src/proto_syntax.py b/src/proto_syntax.py
index 0d1496a..3e2220c 100644
--- a/src/proto_syntax.py
+++ b/src/proto_syntax.py
@@ -16,7 +16,8 @@ class ProtoSyntaxType(Enum):
class ProtoSyntax(ProtoNode):
- def __init__(self, syntax: ProtoStringLiteral):
+ def __init__(self, parent: Optional[ProtoNode], syntax: ProtoStringLiteral):
+ super().__init__(parent)
self.syntax = syntax
def __eq__(self, other) -> bool:
@@ -35,11 +36,13 @@ def normalize(self) -> "ProtoSyntax":
return self
@classmethod
- def match(cls, proto_source: str) -> Optional["ParsedProtoSyntaxNode"]:
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoSyntaxNode"]:
if not proto_source.startswith("syntax = "):
return None
proto_source = proto_source[9:]
- match = ProtoStringLiteral.match(proto_source)
+ match = ProtoStringLiteral.match(None, proto_source)
if match is None:
raise ValueError(f"Proto has invalid syntax syntax: {proto_source}")
if not match.remaining_source.startswith(";"):
@@ -52,7 +55,7 @@ def match(cls, proto_source: str) -> Optional["ParsedProtoSyntaxNode"]:
)
return ParsedProtoSyntaxNode(
- ProtoSyntax(match.node),
+ ProtoSyntax(parent, match.node),
match.remaining_source.strip(),
)
diff --git a/test/parser_test.py b/test/parser_test.py
index 7f42e1a..a9859c3 100644
--- a/test/parser_test.py
+++ b/test/parser_test.py
@@ -103,44 +103,54 @@ def test_parser(self):
self.assertEqual(
proto_file.imports,
[
- ProtoImport(ProtoStringLiteral("foo.proto"), public=True),
- ProtoImport(ProtoStringLiteral("bar/baz.proto"), weak=True),
- ProtoImport(ProtoStringLiteral("bat.proto")),
+ ProtoImport(None, ProtoStringLiteral(None, "foo.proto"), public=True),
+ ProtoImport(None, ProtoStringLiteral(None, "bar/baz.proto"), weak=True),
+ ProtoImport(None, ProtoStringLiteral(None, "bat.proto")),
],
)
self.assertEqual(
proto_file.options,
[
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("my.test.package")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "my.test.package")),
),
ProtoOption(
- ProtoIdentifier("(fully.qualified).option"),
- ProtoConstant(ProtoFloat(3.14159265, ProtoFloatSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "(fully.qualified).option"),
+ ProtoConstant(
+ None, ProtoFloat(None, 3.14159265, ProtoFloatSign.POSITIVE)
+ ),
),
],
)
self.assertIn(
ProtoEnum(
- ProtoIdentifier("MyAwesomeEnum"),
+ None,
+ ProtoIdentifier(None, "MyAwesomeEnum"),
[
ProtoOption(
- ProtoIdentifier("allow_alias"), ProtoConstant(ProtoBool(True))
+ None,
+ ProtoIdentifier(None, "allow_alias"),
+ ProtoConstant(None, ProtoBool(None, True)),
),
ProtoEnumValue(
- ProtoIdentifier("MAE_UNSPECIFIED"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "MAE_UNSPECIFIED"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
[],
),
ProtoEnumValue(
- ProtoIdentifier("MAE_STARTED"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "MAE_STARTED"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
[],
),
ProtoEnumValue(
- ProtoIdentifier("MAE_RUNNING"),
- ProtoInt(2, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "MAE_RUNNING"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
[],
),
],
@@ -149,89 +159,113 @@ def test_parser(self):
)
self.assertIn(
ProtoMessage(
- ProtoIdentifier("MyAwesomeMessage"),
+ None,
+ ProtoIdentifier(None, "MyAwesomeMessage"),
[
ProtoOption(
- ProtoIdentifier("(bar).baz"),
- ProtoConstant(ProtoFloat(1.2, ProtoFloatSign.POSITIVE)),
+ None,
+ ProtoFullIdentifier(None, "(bar).baz"),
+ ProtoConstant(
+ None, ProtoFloat(None, 1.2, ProtoFloatSign.POSITIVE)
+ ),
),
ProtoEnum(
- ProtoIdentifier("MyNestedEnum"),
+ None,
+ ProtoIdentifier(None, "MyNestedEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("MNE_UNDEFINED"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "MNE_UNDEFINED"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- ProtoIdentifier("MNE_NEGATIVE"),
- ProtoInt(1, ProtoIntSign.NEGATIVE),
+ None,
+ ProtoIdentifier(None, "MNE_NEGATIVE"),
+ ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
),
ProtoEnumValue(
- ProtoIdentifier("MNE_POSITIVE"),
- ProtoInt(2, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "MNE_POSITIVE"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
),
],
),
- ProtoMessage(ProtoIdentifier("MyNestedMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "MyNestedMessage"), []),
ProtoReserved(
+ None,
ranges=[
ProtoRange(
- ProtoInt(1, ProtoIntSign.POSITIVE),
- ProtoInt(3, ProtoIntSign.POSITIVE),
+ None,
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
)
- ]
+ ],
),
- ProtoReserved(fields=[ProtoIdentifier("yay")]),
- ProtoSingleLineComment(" testing nested comment"),
+ ProtoReserved(None, fields=[ProtoIdentifier(None, "yay")]),
+ ProtoSingleLineComment(None, " testing nested comment"),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("field_one"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "field_one"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
True,
),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("field_two"),
- ProtoInt(2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "field_two"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
False,
False,
- ProtoIdentifier("MyNestedMessage"),
+ ProtoIdentifier(None, "MyNestedMessage"),
[
ProtoMessageFieldOption(
- ProtoFullIdentifier("bar.baz"),
- ProtoConstant(ProtoBool(True)),
+ None,
+ ProtoFullIdentifier(None, "bar.baz"),
+ ProtoConstant(None, ProtoBool(None, True)),
)
],
),
- ProtoExtensions([ProtoRange(8, ProtoRangeEnum.MAX)]),
+ ProtoExtensions(None, [ProtoRange(None, 8, ProtoRangeEnum.MAX)]),
ProtoOneOf(
- ProtoIdentifier("foo"),
+ None,
+ ProtoIdentifier(None, "foo"),
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "name"),
+ ProtoInt(None, 4, ProtoIntSign.POSITIVE),
),
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(
+ None, ProtoStringLiteral(None, "com.example.foo")
+ ),
),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("sub_message"),
- ProtoInt(9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "sub_message"),
+ ProtoInt(None, 9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier("SubMessage"),
+ ProtoFullIdentifier(None, "SubMessage"),
[
ProtoMessageFieldOption(
- ProtoIdentifier("(bar.baz).bat"),
- ProtoConstant(ProtoStringLiteral("bat")),
+ None,
+ ProtoIdentifier(None, "(bar.baz).bat"),
+ ProtoConstant(
+ None, ProtoStringLiteral(None, "bat")
+ ),
),
ProtoMessageFieldOption(
- ProtoIdentifier("baz.bat"),
+ None,
+ ProtoIdentifier(None, "baz.bat"),
ProtoConstant(
- ProtoInt(100, ProtoIntSign.NEGATIVE)
+ None,
+ ProtoInt(None, 100, ProtoIntSign.NEGATIVE),
),
),
],
@@ -239,11 +273,12 @@ def test_parser(self):
],
),
ProtoMap(
+ None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("my_map"),
- ProtoInt(10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier("NestedMessage"),
+ ProtoIdentifier(None, "my_map"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
[],
),
],
@@ -253,38 +288,47 @@ def test_parser(self):
self.assertIn(
ProtoService(
- ProtoIdentifier("MyGreatService"),
+ None,
+ ProtoIdentifier(None, "MyGreatService"),
[
ProtoOption(
- ProtoIdentifier("(foo.bar).baz"),
- ProtoConstant(ProtoStringLiteral("bat")),
+ None,
+ ProtoIdentifier(None, "(foo.bar).baz"),
+ ProtoConstant(None, ProtoStringLiteral(None, "bat")),
),
ProtoServiceRPC(
- ProtoIdentifier("OneRPC"),
- ProtoEnumOrMessageIdentifier("OneRPCRequest"),
- ProtoEnumOrMessageIdentifier("OneRPCResponse"),
+ None,
+ ProtoIdentifier(None, "OneRPC"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
),
ProtoServiceRPC(
- ProtoIdentifier("TwoRPC"),
- ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
+ None,
+ ProtoIdentifier(None, "TwoRPC"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
False,
True,
),
ProtoServiceRPC(
- ProtoIdentifier("ThreeRPC"),
- ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
+ None,
+ ProtoIdentifier(None, "ThreeRPC"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
False,
False,
[
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(
+ None, ProtoStringLiteral(None, "com.example.foo")
+ ),
),
ProtoOption(
- ProtoFullIdentifier("(foo.bar).baz"),
- ProtoConstant(ProtoBool(False)),
+ None,
+ ProtoFullIdentifier(None, "(foo.bar).baz"),
+ ProtoConstant(None, ProtoBool(None, False)),
),
],
),
@@ -295,14 +339,16 @@ def test_parser(self):
self.assertIn(
ProtoExtend(
- ProtoIdentifier("SomeExtendableMessage"),
+ None,
+ ProtoIdentifier(None, "SomeExtendableMessage"),
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("some_extendable_field"),
- 1,
+ ProtoIdentifier(None, "some_extendable_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
- ProtoSingleLineComment(" yay"),
+ ProtoSingleLineComment(None, " yay"),
],
),
proto_file.nodes,
diff --git a/test/proto_bool_test.py b/test/proto_bool_test.py
index cc3a035..7611d75 100644
--- a/test/proto_bool_test.py
+++ b/test/proto_bool_test.py
@@ -5,18 +5,18 @@
class BoolTest(unittest.TestCase):
def test_true(self):
- self.assertEqual(ProtoBool.match("true").node.value, True)
- self.assertIsNone(ProtoBool.match("True"))
- self.assertIsNone(ProtoBool.match("truee"))
- self.assertIsNone(ProtoBool.match("true_true"))
- self.assertIsNone(ProtoBool.match("true.false"))
+ self.assertEqual(ProtoBool.match(None, "true").node.value, True)
+ self.assertIsNone(ProtoBool.match(None, "True"))
+ self.assertIsNone(ProtoBool.match(None, "truee"))
+ self.assertIsNone(ProtoBool.match(None, "true_true"))
+ self.assertIsNone(ProtoBool.match(None, "true.false"))
def test_false(self):
- self.assertEqual(ProtoBool.match("false").node.value, False)
- self.assertIsNone(ProtoBool.match("False"))
- self.assertIsNone(ProtoBool.match("falsee"))
- self.assertIsNone(ProtoBool.match("false_false"))
- self.assertIsNone(ProtoBool.match("false.true"))
+ self.assertEqual(ProtoBool.match(None, "false").node.value, False)
+ self.assertIsNone(ProtoBool.match(None, "False"))
+ self.assertIsNone(ProtoBool.match(None, "falsee"))
+ self.assertIsNone(ProtoBool.match(None, "false_false"))
+ self.assertIsNone(ProtoBool.match(None, "false.true"))
if __name__ == "__main__":
diff --git a/test/proto_comment_test.py b/test/proto_comment_test.py
index 95a37e9..5d3a705 100644
--- a/test/proto_comment_test.py
+++ b/test/proto_comment_test.py
@@ -5,42 +5,46 @@
class ProtoSingleLineCommentTest(unittest.TestCase):
def test_matches_normal_comment(self):
- node = ProtoSingleLineComment.match("// hello there, this is a comment").node
+ node = ProtoSingleLineComment.match(
+ None, "// hello there, this is a comment"
+ ).node
self.assertEqual(node.value, " hello there, this is a comment")
self.assertEqual(node.serialize(), "// hello there, this is a comment")
self.assertIsNone(node.normalize())
def test_matches_without_space(self):
- node = ProtoSingleLineComment.match("//comment without space").node
+ node = ProtoSingleLineComment.match(None, "//comment without space").node
self.assertEqual(node.value, "comment without space")
self.assertEqual(node.serialize(), "//comment without space")
self.assertIsNone(node.normalize())
def test_does_not_match_multiple_lines(self):
- node = ProtoSingleLineComment.match("//line one\nbut not this").node
+ node = ProtoSingleLineComment.match(None, "//line one\nbut not this").node
self.assertEqual(node.value, "line one")
self.assertEqual(node.serialize(), "//line one")
self.assertIsNone(node.normalize())
def test_does_not_match_single_slash(self):
self.assertIsNone(
- ProtoSingleLineComment.match("/hello there, this is a comment")
+ ProtoSingleLineComment.match(None, "/hello there, this is a comment")
)
self.assertIsNone(
- ProtoSingleLineComment.match("/ /hello there, this is a comment")
+ ProtoSingleLineComment.match(None, "/ /hello there, this is a comment")
)
class ProtoMultiLineCommentTest(unittest.TestCase):
def test_matches_single_line_comment(self):
- node = ProtoMultiLineComment.match("/* hello there, this is a comment */").node
+ node = ProtoMultiLineComment.match(
+ None, "/* hello there, this is a comment */"
+ ).node
self.assertEqual(node.value, " hello there, this is a comment ")
self.assertEqual(node.serialize(), "/* hello there, this is a comment */")
self.assertIsNone(node.normalize())
def test_matches_multi_line_comment(self):
node = ProtoMultiLineComment.match(
- "/* hello there,\nthis is a \nmulti-line comment */"
+ None, "/* hello there,\nthis is a \nmulti-line comment */"
).node
self.assertEqual(node.value, " hello there,\nthis is a \nmulti-line comment ")
self.assertEqual(
@@ -51,25 +55,25 @@ def test_matches_multi_line_comment(self):
def test_does_not_match_unclosed_comment(self):
self.assertIsNone(
ProtoMultiLineComment.match(
- "/* hello there, this\n /is an unclosed\n*multiple-line comment/"
+ None, "/* hello there, this\n /is an unclosed\n*multiple-line comment/"
)
)
def test_matches_without_space(self):
- node = ProtoMultiLineComment.match("/*comment without space*/").node
+ node = ProtoMultiLineComment.match(None, "/*comment without space*/").node
self.assertEqual(node.value, "comment without space")
self.assertEqual(node.serialize(), "/*comment without space*/")
self.assertIsNone(node.normalize())
def test_does_not_match_partial_opening(self):
self.assertIsNone(
- ProtoMultiLineComment.match("/hello there, this is a comment*/")
+ ProtoMultiLineComment.match(None, "/hello there, this is a comment*/")
)
self.assertIsNone(
- ProtoMultiLineComment.match("*/hello there, this is a comment*/")
+ ProtoMultiLineComment.match(None, "*/hello there, this is a comment*/")
)
self.assertIsNone(
- ProtoMultiLineComment.match("*hello there, this is a comment*/")
+ ProtoMultiLineComment.match(None, "*hello there, this is a comment*/")
)
diff --git a/test/proto_constant_test.py b/test/proto_constant_test.py
index 2717fa4..3367770 100644
--- a/test/proto_constant_test.py
+++ b/test/proto_constant_test.py
@@ -12,151 +12,174 @@
class ConstantTest(unittest.TestCase):
# constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) | strLit | boolLit
def test_ident(self):
- self.assertEqual(ProtoConstant.match("a").node.value, ProtoIdentifier("a"))
- self.assertEqual(ProtoConstant.match("a0").node.value, ProtoIdentifier("a0"))
- self.assertEqual(ProtoConstant.match("a_").node.value, ProtoIdentifier("a_"))
- self.assertEqual(ProtoConstant.match("aa").node.value, ProtoIdentifier("aa"))
- self.assertEqual(ProtoConstant.match("ab").node.value, ProtoIdentifier("ab"))
self.assertEqual(
- ProtoConstant.match("a0b_f_aj").node.value, ProtoIdentifier("a0b_f_aj")
+ ProtoConstant.match(None, "a").node.value, ProtoIdentifier(None, "a")
)
self.assertEqual(
- ProtoConstant.match("a.bar").node.value, ProtoIdentifier("a.bar")
+ ProtoConstant.match(None, "a0").node.value, ProtoIdentifier(None, "a0")
)
self.assertEqual(
- ProtoConstant.match("a.bar.baz").node.value, ProtoIdentifier("a.bar.baz")
+ ProtoConstant.match(None, "a_").node.value, ProtoIdentifier(None, "a_")
+ )
+ self.assertEqual(
+ ProtoConstant.match(None, "aa").node.value, ProtoIdentifier(None, "aa")
+ )
+ self.assertEqual(
+ ProtoConstant.match(None, "ab").node.value, ProtoIdentifier(None, "ab")
+ )
+ self.assertEqual(
+ ProtoConstant.match(None, "a0b_f_aj").node.value,
+ ProtoIdentifier(None, "a0b_f_aj"),
+ )
+ self.assertEqual(
+ ProtoConstant.match(None, "a.bar").node.value,
+ ProtoIdentifier(None, "a.bar"),
+ )
+ self.assertEqual(
+ ProtoConstant.match(None, "a.bar.baz").node.value,
+ ProtoIdentifier(None, "a.bar.baz"),
)
def test_str(self):
self.assertEqual(
- ProtoConstant.match("'a'").node.value, ProtoStringLiteral("a", quote="'")
+ ProtoConstant.match(None, "'a'").node.value,
+ ProtoStringLiteral(None, "a", quote="'"),
)
self.assertEqual(
- ProtoConstant.match("'.a'").node.value, ProtoStringLiteral(".a", quote="'")
+ ProtoConstant.match(None, "'.a'").node.value,
+ ProtoStringLiteral(None, ".a", quote="'"),
)
self.assertEqual(
- ProtoConstant.match('"a"').node.value, ProtoStringLiteral("a", quote='"')
+ ProtoConstant.match(None, '"a"').node.value,
+ ProtoStringLiteral(None, "a", quote='"'),
)
def test_bool(self):
- self.assertEqual(ProtoConstant.match("true").node.value, ProtoBool(True))
- self.assertEqual(ProtoConstant.match("false").node.value, ProtoBool(False))
+ self.assertEqual(
+ ProtoConstant.match(None, "true").node.value, ProtoBool(None, True)
+ )
+ self.assertEqual(
+ ProtoConstant.match(None, "false").node.value, ProtoBool(None, False)
+ )
def test_int(self):
self.assertEqual(
- ProtoConstant.match("1").node.value, ProtoInt(1, ProtoIntSign.POSITIVE)
+ ProtoConstant.match(None, "1").node.value,
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("158912938471293847").node.value,
- ProtoInt(158912938471293847, ProtoIntSign.POSITIVE),
+ ProtoConstant.match(None, "158912938471293847").node.value,
+ ProtoInt(None, 158912938471293847, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("+1").node.value, ProtoInt(1, ProtoIntSign.POSITIVE)
+ ProtoConstant.match(None, "+1").node.value,
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("+158912938471293847").node.value,
- ProtoInt(158912938471293847, ProtoIntSign.POSITIVE),
+ ProtoConstant.match(None, "+158912938471293847").node.value,
+ ProtoInt(None, 158912938471293847, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("-1").node.value, ProtoInt(1, ProtoIntSign.NEGATIVE)
+ ProtoConstant.match(None, "-1").node.value,
+ ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
)
self.assertEqual(
- ProtoConstant.match("-248713857").node.value,
- ProtoInt(248713857, ProtoIntSign.NEGATIVE),
+ ProtoConstant.match(None, "-248713857").node.value,
+ ProtoInt(None, 248713857, ProtoIntSign.NEGATIVE),
)
# Octal
self.assertEqual(
- ProtoConstant.match("072342").node.value,
- ProtoInt(0o72342, ProtoIntSign.POSITIVE),
+ ProtoConstant.match(None, "072342").node.value,
+ ProtoInt(None, 0o72342, ProtoIntSign.POSITIVE),
)
with self.assertRaises(ValueError):
- ProtoConstant.match("072942")
+ ProtoConstant.match(None, "072942")
# Hex
self.assertEqual(
- ProtoConstant.match("0x72342").node.value,
- ProtoInt(0x72342, ProtoIntSign.POSITIVE),
+ ProtoConstant.match(None, "0x72342").node.value,
+ ProtoInt(None, 0x72342, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("0x7A3d2").node.value,
- ProtoInt(0x7A3D2, ProtoIntSign.POSITIVE),
+ ProtoConstant.match(None, "0x7A3d2").node.value,
+ ProtoInt(None, 0x7A3D2, ProtoIntSign.POSITIVE),
)
with self.assertRaises(ValueError):
- ProtoConstant.match("0x72G42")
+ ProtoConstant.match(None, "0x72G42")
def test_float(self):
self.assertEqual(
- ProtoConstant.match("2834.235928").node.value,
- ProtoFloat(2834.235928, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834.235928").node.value,
+ ProtoFloat(None, 2834.235928, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834.e2").node.value,
- ProtoFloat(283400, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834.e2").node.value,
+ ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834e2").node.value,
- ProtoFloat(283400, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834e2").node.value,
+ ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834.e0").node.value,
- ProtoFloat(2834, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834.e0").node.value,
+ ProtoFloat(None, 2834, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834e0").node.value,
- ProtoFloat(2834, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834e0").node.value,
+ ProtoFloat(None, 2834, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834.E3").node.value,
- ProtoFloat(2834000, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834.E3").node.value,
+ ProtoFloat(None, 2834000, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834E3").node.value,
- ProtoFloat(2834000, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834E3").node.value,
+ ProtoFloat(None, 2834000, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834.e+2").node.value,
- ProtoFloat(283400, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834.e+2").node.value,
+ ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834e+2").node.value,
- ProtoFloat(283400, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834e+2").node.value,
+ ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834.e-2").node.value,
- ProtoFloat(28.34, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834.e-2").node.value,
+ ProtoFloat(None, 28.34, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("2834e-2").node.value,
- ProtoFloat(28.34, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "2834e-2").node.value,
+ ProtoFloat(None, 28.34, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(".0").node.value,
- ProtoFloat(0.0, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, ".0").node.value,
+ ProtoFloat(None, 0.0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(".0e-1").node.value,
- ProtoFloat(0.00, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, ".0e-1").node.value,
+ ProtoFloat(None, 0.00, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(".0E1").node.value,
- ProtoFloat(0, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, ".0E1").node.value,
+ ProtoFloat(None, 0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(".0E2").node.value,
- ProtoFloat(0, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, ".0E2").node.value,
+ ProtoFloat(None, 0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(".3265").node.value,
- ProtoFloat(0.3265, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, ".3265").node.value,
+ ProtoFloat(None, 0.3265, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(".3265e1").node.value,
- ProtoFloat(3.265, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, ".3265e1").node.value,
+ ProtoFloat(None, 3.265, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match("inf").node.value,
- ProtoFloat(float("inf"), ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(None, "inf").node.value,
+ ProtoFloat(None, float("inf"), ProtoFloatSign.POSITIVE),
)
diff --git a/test/proto_enum_test.py b/test/proto_enum_test.py
index 4687151..1efafc7 100644
--- a/test/proto_enum_test.py
+++ b/test/proto_enum_test.py
@@ -26,6 +26,7 @@ class EnumTest(unittest.TestCase):
def test_enum_all_features(self):
parsed_enum_multiple_values = ProtoEnum.match(
+ None,
dedent(
"""
enum FooEnum {
@@ -43,60 +44,81 @@ def test_enum_all_features(self):
FE_VALTWO = 2;
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_enum_multiple_values.node.nodes,
[
ProtoReserved(
+ None,
[
- ProtoRange(ProtoInt(1, ProtoIntSign.POSITIVE)),
- ProtoRange(ProtoInt(2, ProtoIntSign.POSITIVE)),
+ ProtoRange(None, ProtoInt(None, 1, ProtoIntSign.POSITIVE)),
+ ProtoRange(None, ProtoInt(None, 2, ProtoIntSign.POSITIVE)),
ProtoRange(
- ProtoInt(5, ProtoIntSign.POSITIVE),
+ None,
+ ProtoInt(None, 5, ProtoIntSign.POSITIVE),
ProtoRangeEnum.MAX,
),
- ]
+ ],
),
ProtoEnumValue(
- ProtoIdentifier("FE_NEGATIVE"),
- ProtoInt(1, ProtoIntSign.NEGATIVE),
+ None,
+ ProtoIdentifier(None, "FE_NEGATIVE"),
+ ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
[
ProtoEnumValueOption(
- ProtoIdentifier("foo"), ProtoConstant(ProtoBool(False))
+ None,
+ ProtoIdentifier(None, "foo"),
+ ProtoConstant(None, ProtoBool(None, False)),
)
],
),
ProtoEnumValue(
- ProtoIdentifier("FE_UNDEFINED"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_UNDEFINED"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
- ProtoSingleLineComment(" single-line comment"),
+ ProtoSingleLineComment(None, " single-line comment"),
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foobar")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foobar")),
),
ProtoMultiLineComment(
- "\n multiple\n line\n comment\n "
+ None,
+ "\n multiple\n line\n comment\n ",
),
ProtoEnumValue(
- ProtoIdentifier("FE_VALONE"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_VALONE"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
[
ProtoEnumValueOption(
- ProtoIdentifier("(bar.baz).bat"),
- ProtoConstant(ProtoStringLiteral("bat")),
+ None,
+ ProtoIdentifier(None, "(bar.baz).bat"),
+ ProtoConstant(None, ProtoStringLiteral(None, "bat")),
),
ProtoEnumValueOption(
- ProtoIdentifier("baz.bat"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
+ None,
+ ProtoIdentifier(None, "baz.bat"),
+ ProtoConstant(
+ None, ProtoInt(None, 100, ProtoIntSign.NEGATIVE)
+ ),
),
],
),
ProtoReserved(
- [], [ProtoIdentifier("FE_RESERVED"), ProtoIdentifier("FE_OLD")]
+ None,
+ [],
+ [
+ ProtoIdentifier(None, "FE_RESERVED"),
+ ProtoIdentifier(None, "FE_OLD"),
+ ],
),
ProtoEnumValue(
- ProtoIdentifier("FE_VALTWO"), ProtoInt(2, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_VALTWO"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
),
],
)
@@ -125,24 +147,26 @@ def test_enum_all_features(self):
)
def test_empty_enum(self):
- parsed_empty_enum = ProtoEnum.match("""enum FooEnum {}""")
+ parsed_empty_enum = ProtoEnum.match(None, """enum FooEnum {}""")
self.assertIsNotNone(parsed_empty_enum)
- self.assertEqual(parsed_empty_enum.node.name, ProtoIdentifier("FooEnum"))
+ self.assertEqual(parsed_empty_enum.node.name, ProtoIdentifier(None, "FooEnum"))
parsed_spaced_enum = ProtoEnum.match(
+ None,
dedent(
"""
enum FooEnum {
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(parsed_spaced_enum)
- self.assertEqual(parsed_spaced_enum.node.name, ProtoIdentifier("FooEnum"))
+ self.assertEqual(parsed_spaced_enum.node.name, ProtoIdentifier(None, "FooEnum"))
def test_enum_empty_statements(self):
empty_statement_enum = ProtoEnum.match(
+ None,
dedent(
"""
enum FooEnum {
@@ -150,13 +174,16 @@ def test_enum_empty_statements(self):
;
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(empty_statement_enum)
- self.assertEqual(empty_statement_enum.node.name, ProtoIdentifier("FooEnum"))
+ self.assertEqual(
+ empty_statement_enum.node.name, ProtoIdentifier(None, "FooEnum")
+ )
def test_enum_optionals(self):
parsed_enum_with_optionals = ProtoEnum.match(
+ None,
dedent(
"""
enum FooEnum {
@@ -164,46 +191,52 @@ def test_enum_optionals(self):
option (foo.bar).baz = false;
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(
parsed_enum_with_optionals.node.options,
[
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foobar")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foobar")),
),
ProtoOption(
- ProtoIdentifier("(foo.bar).baz"),
- ProtoConstant(ProtoBool(False)),
+ None,
+ ProtoIdentifier(None, "(foo.bar).baz"),
+ ProtoConstant(None, ProtoBool(None, False)),
),
],
)
self.assertEqual(
- parsed_enum_with_optionals.node.name, ProtoIdentifier("FooEnum")
+ parsed_enum_with_optionals.node.name, ProtoIdentifier(None, "FooEnum")
)
def test_enum_single_value(self):
parsed_enum_single_value = ProtoEnum.match(
+ None,
dedent(
"""
enum FooEnum {
FE_UNDEFINED = 0;
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_enum_single_value.node.nodes,
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNDEFINED"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_UNDEFINED"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
)
def test_enum_multiple_values(self):
parsed_enum_multiple_values = ProtoEnum.match(
+ None,
dedent(
"""
enum FooEnum {
@@ -213,28 +246,37 @@ def test_enum_multiple_values(self):
FE_VALTWO = 2;
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_enum_multiple_values.node.nodes,
[
ProtoEnumValue(
- ProtoIdentifier("FE_NEGATIVE"), ProtoInt(1, ProtoIntSign.NEGATIVE)
+ None,
+ ProtoIdentifier(None, "FE_NEGATIVE"),
+ ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
),
ProtoEnumValue(
- ProtoIdentifier("FE_UNDEFINED"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_UNDEFINED"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- ProtoIdentifier("FE_VALONE"), ProtoInt(1, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_VALONE"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- ProtoIdentifier("FE_VALTWO"), ProtoInt(2, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_VALTWO"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
),
],
)
def test_enum_comments(self):
parsed_enum_multiple_values = ProtoEnum.match(
+ None,
dedent(
"""
enum FooEnum {
@@ -246,32 +288,42 @@ def test_enum_comments(self):
FE_VALTWO = 2;
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_enum_multiple_values.node.nodes,
[
ProtoEnumValue(
- ProtoIdentifier("FE_NEGATIVE"), ProtoInt(1, ProtoIntSign.NEGATIVE)
+ None,
+ ProtoIdentifier(None, "FE_NEGATIVE"),
+ ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
),
- ProtoSingleLineComment(" test single-line comment"),
+ ProtoSingleLineComment(None, " test single-line comment"),
ProtoEnumValue(
- ProtoIdentifier("FE_UNDEFINED"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_UNDEFINED"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
ProtoMultiLineComment(
- " test multiple\n FE_UNUSED = 200;\n line comment "
+ None,
+ " test multiple\n FE_UNUSED = 200;\n line comment ",
),
ProtoEnumValue(
- ProtoIdentifier("FE_VALONE"), ProtoInt(1, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_VALONE"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- ProtoIdentifier("FE_VALTWO"), ProtoInt(2, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_VALTWO"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
),
],
)
def test_enum_normalize_away_comments(self):
parsed_enum_multiple_values = ProtoEnum.match(
+ None,
dedent(
"""
enum FooEnum {
@@ -283,62 +335,80 @@ def test_enum_normalize_away_comments(self):
FE_VALTWO = 2;
}
""".strip()
- )
+ ),
).node.normalize()
self.assertEqual(
parsed_enum_multiple_values.nodes,
[
ProtoEnumValue(
- ProtoIdentifier("FE_NEGATIVE"), ProtoInt(1, ProtoIntSign.NEGATIVE)
+ None,
+ ProtoIdentifier(None, "FE_NEGATIVE"),
+ ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
),
ProtoEnumValue(
- ProtoIdentifier("FE_UNDEFINED"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_UNDEFINED"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- ProtoIdentifier("FE_VALONE"), ProtoInt(1, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_VALONE"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- ProtoIdentifier("FE_VALTWO"), ProtoInt(2, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "FE_VALTWO"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
),
],
)
def test_diff_same_enum_returns_empty(self):
pe1 = ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[],
)
pe2 = ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[],
)
self.assertEqual(ProtoEnum.diff(pe1, pe2), [])
def test_diff_different_enum_name_returns_empty(self):
pe1 = ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[],
)
pe2 = ProtoEnum(
- ProtoIdentifier("OtherEnum"),
+ None,
+ ProtoIdentifier(None, "OtherEnum"),
[],
)
self.assertEqual(ProtoEnum.diff(pe1, pe2), [])
def test_diff_different_enum_value_name_returns_enum_diff(self):
pe1 = ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "ME_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
)
pe2 = ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_KNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "ME_KNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
)
@@ -348,25 +418,31 @@ def test_diff_different_enum_value_name_returns_enum_diff(self):
ProtoEnumValueNameChanged(
pe1,
pe2.nodes[0],
- ProtoIdentifier("ME_UNKNOWN"),
+ ProtoIdentifier(None, "ME_UNKNOWN"),
)
],
)
def test_diff_different_enum_value_value_returns_enum_diff(self):
pe1 = ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "ME_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
)
pe2 = ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_UNKNOWN"), ProtoInt(1, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "ME_UNKNOWN"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
)
],
)
@@ -377,7 +453,7 @@ def test_diff_different_enum_value_value_returns_enum_diff(self):
ProtoEnumValueValueChanged(
pe1,
pe2.values[0],
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
diff,
)
@@ -386,10 +462,13 @@ def test_diff_different_enum_value_value_returns_enum_diff(self):
def test_diff_enum_added(self):
pe1 = None
pe2 = ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "ME_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
)
@@ -398,11 +477,13 @@ def test_diff_enum_added(self):
[
ProtoEnumAdded(
ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "ME_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
)
@@ -412,10 +493,13 @@ def test_diff_enum_added(self):
def test_diff_enum_removed(self):
pe1 = ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_UNKNOWN"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "ME_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
)
@@ -425,11 +509,13 @@ def test_diff_enum_removed(self):
[
ProtoEnumRemoved(
ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "ME_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
)
@@ -445,29 +531,35 @@ def test_diff_sets_empty_returns_empty(self):
def test_diff_sets_no_change(self):
set1 = [
ProtoEnum(
- ProtoIdentifier("FooEnum"),
+ None,
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("TagEnum"),
+ None,
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -478,29 +570,35 @@ def test_diff_sets_all_removed(self):
set1 = []
set2 = [
ProtoEnum(
- ProtoIdentifier("FooEnum"),
+ None,
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("TagEnum"),
+ None,
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -510,11 +608,13 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- ProtoIdentifier("FooEnum"),
+ None,
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -524,11 +624,13 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -538,11 +640,13 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- ProtoIdentifier("TagEnum"),
+ None,
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -554,29 +658,35 @@ def test_diff_sets_all_removed(self):
def test_diff_sets_all_added(self):
set1 = [
ProtoEnum(
- ProtoIdentifier("FooEnum"),
+ None,
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("TagEnum"),
+ None,
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -587,11 +697,13 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- ProtoIdentifier("FooEnum"),
+ None,
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -601,11 +713,13 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -615,11 +729,13 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- ProtoIdentifier("TagEnum"),
+ None,
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -631,58 +747,70 @@ def test_diff_sets_all_added(self):
def test_diff_sets_mutually_exclusive(self):
set1 = [
ProtoEnum(
- ProtoIdentifier("FooEnum"),
+ None,
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("TagEnum"),
+ None,
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
]
set2 = [
ProtoEnum(
- ProtoIdentifier("FooEnum2"),
+ None,
+ ProtoIdentifier(None, "FooEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("BarEnum2"),
+ None,
+ ProtoIdentifier(None, "BarEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("TagEnum2"),
+ None,
+ ProtoIdentifier(None, "TagEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -693,11 +821,13 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- ProtoIdentifier("FooEnum"),
+ None,
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -707,11 +837,13 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -722,11 +854,13 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- ProtoIdentifier("TagEnum"),
+ None,
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -737,11 +871,13 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- ProtoIdentifier("FooEnum2"),
+ None,
+ ProtoIdentifier(None, "FooEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -752,11 +888,13 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- ProtoIdentifier("BarEnum2"),
+ None,
+ ProtoIdentifier(None, "BarEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -767,11 +905,13 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- ProtoIdentifier("TagEnum2"),
+ None,
+ ProtoIdentifier(None, "TagEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -784,58 +924,70 @@ def test_diff_sets_mutually_exclusive(self):
def test_diff_sets_overlap(self):
set1 = [
ProtoEnum(
- ProtoIdentifier("FooEnum"),
+ None,
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("TagEnum"),
+ None,
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
]
set2 = [
ProtoEnum(
- ProtoIdentifier("FooEnum2"),
+ None,
+ ProtoIdentifier(None, "FooEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- ProtoIdentifier("TagEnum2"),
+ None,
+ ProtoIdentifier(None, "TagEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -846,11 +998,13 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- ProtoIdentifier("FooEnum2"),
+ None,
+ ProtoIdentifier(None, "FooEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -861,11 +1015,13 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- ProtoIdentifier("TagEnum2"),
+ None,
+ ProtoIdentifier(None, "TagEnum2"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN2"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -875,11 +1031,13 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- ProtoIdentifier("FooEnum"),
+ None,
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("FE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -889,11 +1047,13 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- ProtoIdentifier("TagEnum"),
+ None,
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("TE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
@@ -903,18 +1063,22 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumValueNameChanged(
ProtoEnum(
- ProtoIdentifier("BarEnum"),
+ None,
+ ProtoIdentifier(None, "BarEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnumValue(
- ProtoIdentifier("BE_UNKNOWN2"), ProtoInt(0, ProtoIntSign.POSITIVE)
+ None,
+ ProtoIdentifier(None, "BE_UNKNOWN2"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
- ProtoIdentifier("BE_UNKNOWN"),
+ ProtoIdentifier(None, "BE_UNKNOWN"),
),
diff,
)
diff --git a/test/proto_extend_test.py b/test/proto_extend_test.py
index 41d54fc..b77170b 100644
--- a/test/proto_extend_test.py
+++ b/test/proto_extend_test.py
@@ -11,43 +11,47 @@ class ExtendTest(unittest.TestCase):
maxDiff = None
def test_empty_extend(self):
- parsed_empty_extend = ProtoExtend.match("""extend FooMessage {}""")
+ parsed_empty_extend = ProtoExtend.match(None, """extend FooMessage {}""")
self.assertIsNotNone(parsed_empty_extend)
self.assertEqual(
- parsed_empty_extend.node.name, ProtoEnumOrMessageIdentifier("FooMessage")
+ parsed_empty_extend.node.name,
+ ProtoEnumOrMessageIdentifier(None, "FooMessage"),
)
self.assertEqual(parsed_empty_extend.node.serialize(), "extend FooMessage {\n}")
parsed_spaced_extend = ProtoExtend.match(
+ None,
dedent(
"""
extend FooMessage {
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(parsed_spaced_extend)
self.assertEqual(
- parsed_spaced_extend.node.name, ProtoEnumOrMessageIdentifier("FooMessage")
+ parsed_spaced_extend.node.name,
+ ProtoEnumOrMessageIdentifier(None, "FooMessage"),
)
self.assertEqual(
parsed_spaced_extend.node.serialize(), "extend FooMessage {\n}"
)
parsed_scoped_extend = ProtoExtend.match(
+ None,
dedent(
"""
extend google.protobuf.FooMessage {
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(parsed_scoped_extend)
self.assertEqual(
parsed_scoped_extend.node.name,
- ProtoEnumOrMessageIdentifier("google.protobuf.FooMessage"),
+ ProtoEnumOrMessageIdentifier(None, "google.protobuf.FooMessage"),
)
self.assertEqual(
parsed_scoped_extend.node.serialize(),
@@ -56,6 +60,7 @@ def test_empty_extend(self):
def test_extend_empty_statements(self):
empty_statement_message = ProtoExtend.match(
+ None,
dedent(
"""
extend FooMessage {
@@ -63,12 +68,12 @@ def test_extend_empty_statements(self):
;
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(empty_statement_message)
self.assertEqual(
empty_statement_message.node.name,
- ProtoEnumOrMessageIdentifier("FooMessage"),
+ ProtoEnumOrMessageIdentifier(None, "FooMessage"),
)
self.assertEqual(
empty_statement_message.node.serialize(), "extend FooMessage {\n}"
@@ -76,23 +81,26 @@ def test_extend_empty_statements(self):
def test_extend_simple_field(self):
parsed_extend_with_single_field = ProtoExtend.match(
+ None,
dedent(
"""
extend FooMessage {
string single_field = 1;
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_extend_with_single_field.node,
ProtoExtend(
- ProtoEnumOrMessageIdentifier("FooMessage"),
+ None,
+ ProtoEnumOrMessageIdentifier(None, "FooMessage"),
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("single_field"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "single_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
)
],
),
diff --git a/test/proto_extensions_test.py b/test/proto_extensions_test.py
index 2e846a2..86f64c4 100644
--- a/test/proto_extensions_test.py
+++ b/test/proto_extensions_test.py
@@ -6,27 +6,29 @@
class ExtensionsTest(unittest.TestCase):
def test_extension_single_int(self):
self.assertEqual(
- ProtoExtensions.match("extensions 21;").node.serialize(), "extensions 21;"
+ ProtoExtensions.match(None, "extensions 21;").node.serialize(),
+ "extensions 21;",
)
self.assertEqual(
- ProtoExtensions.match("extensions -1;").node.serialize(), "extensions -1;"
+ ProtoExtensions.match(None, "extensions -1;").node.serialize(),
+ "extensions -1;",
)
def test_extension_multiple_ints(self):
self.assertEqual(
- ProtoExtensions.match("extensions 1, 5, 2, 42;").node.serialize(),
+ ProtoExtensions.match(None, "extensions 1, 5, 2, 42;").node.serialize(),
"extensions 1, 5, 2, 42;",
)
def test_extension_with_max(self):
self.assertEqual(
- ProtoExtensions.match("extensions 8 to max;").node.serialize(),
+ ProtoExtensions.match(None, "extensions 8 to max;").node.serialize(),
"extensions 8 to max;",
)
def test_extension_cannot_have_strings(self):
- self.assertIsNone(ProtoExtensions.match("extensions 1, 'foo';"))
- self.assertIsNone(ProtoExtensions.match("extensions 'bar';"))
+ self.assertIsNone(ProtoExtensions.match(None, "extensions 1, 'foo';"))
+ self.assertIsNone(ProtoExtensions.match(None, "extensions 'bar';"))
if __name__ == "__main__":
diff --git a/test/proto_float_test.py b/test/proto_float_test.py
index fa3fde7..28eb34e 100644
--- a/test/proto_float_test.py
+++ b/test/proto_float_test.py
@@ -6,78 +6,88 @@
class FloatTest(unittest.TestCase):
def test_float(self):
self.assertEqual(
- ProtoFloat.match("2834.235928").node,
- ProtoFloat(2834.235928, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(None, "2834.235928").node,
+ ProtoFloat(None, 2834.235928, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(".0").node, ProtoFloat(0.0, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, ".0").node,
+ ProtoFloat(None, 0.0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(".3265").node, ProtoFloat(0.3265, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, ".3265").node,
+ ProtoFloat(None, 0.3265, ProtoFloatSign.POSITIVE),
)
def test_inf(self):
self.assertEqual(
- ProtoFloat.match("inf").node,
- ProtoFloat(float("inf"), ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(None, "inf").node,
+ ProtoFloat(None, float("inf"), ProtoFloatSign.POSITIVE),
)
def test_nan(self):
- match = ProtoFloat.match("nan")
+ match = ProtoFloat.match(None, "nan")
self.assertNotEqual(match.node.value, match.node.value)
self.assertEqual(match.remaining_source, "")
self.assertEqual(match.node.sign, ProtoFloatSign.POSITIVE)
def test_exponential_positive(self):
self.assertEqual(
- ProtoFloat.match("2834.e2").node,
- ProtoFloat(283400, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(None, "2834.e2").node,
+ ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match("2834e2").node, ProtoFloat(283400, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, "2834e2").node,
+ ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match("2834.e0").node, ProtoFloat(2834, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, "2834.e0").node,
+ ProtoFloat(None, 2834, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match("2834e0").node, ProtoFloat(2834, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, "2834e0").node,
+ ProtoFloat(None, 2834, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match("2834.E3").node,
- ProtoFloat(2834000, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(None, "2834.E3").node,
+ ProtoFloat(None, 2834000, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match("2834E3").node,
- ProtoFloat(2834000, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(None, "2834E3").node,
+ ProtoFloat(None, 2834000, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match("2834.e+2").node,
- ProtoFloat(283400, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(None, "2834.e+2").node,
+ ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match("2834e+2").node,
- ProtoFloat(283400, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(None, "2834e+2").node,
+ ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(".0E1").node, ProtoFloat(0, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, ".0E1").node,
+ ProtoFloat(None, 0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(".0E2").node, ProtoFloat(0, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, ".0E2").node,
+ ProtoFloat(None, 0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(".3265e1").node, ProtoFloat(3.265, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, ".3265e1").node,
+ ProtoFloat(None, 3.265, ProtoFloatSign.POSITIVE),
)
def test_exponential_negative(self):
self.assertEqual(
- ProtoFloat.match("2834.e-2").node,
- ProtoFloat(28.34, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(None, "2834.e-2").node,
+ ProtoFloat(None, 28.34, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match("2834e-2").node, ProtoFloat(28.34, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, "2834e-2").node,
+ ProtoFloat(None, 28.34, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(".0e-1").node, ProtoFloat(0.00, ProtoFloatSign.POSITIVE)
+ ProtoFloat.match(None, ".0e-1").node,
+ ProtoFloat(None, 0.00, ProtoFloatSign.POSITIVE),
)
diff --git a/test/proto_identifier_test.py b/test/proto_identifier_test.py
index e174296..d1f44d3 100644
--- a/test/proto_identifier_test.py
+++ b/test/proto_identifier_test.py
@@ -10,88 +10,99 @@
class IdentifierTest(unittest.TestCase):
def test_ident(self):
- self.assertEqual(ProtoIdentifier.match("a").node.identifier, "a")
- self.assertEqual(ProtoIdentifier.match("a0").node.identifier, "a0")
- self.assertEqual(ProtoIdentifier.match("a_").node.identifier, "a_")
- self.assertEqual(ProtoIdentifier.match("aa").node.identifier, "aa")
- self.assertEqual(ProtoIdentifier.match("ab").node.identifier, "ab")
- self.assertEqual(ProtoIdentifier.match("a0b_f_aj").node.identifier, "a0b_f_aj")
+ self.assertEqual(ProtoIdentifier.match(None, "a").node.identifier, "a")
+ self.assertEqual(ProtoIdentifier.match(None, "a0").node.identifier, "a0")
+ self.assertEqual(ProtoIdentifier.match(None, "a_").node.identifier, "a_")
+ self.assertEqual(ProtoIdentifier.match(None, "aa").node.identifier, "aa")
+ self.assertEqual(ProtoIdentifier.match(None, "ab").node.identifier, "ab")
+ self.assertEqual(
+ ProtoIdentifier.match(None, "a0b_f_aj").node.identifier, "a0b_f_aj"
+ )
def test_ident_no_leading_letter(self):
- self.assertIsNone(ProtoIdentifier.match("0"))
- self.assertIsNone(ProtoIdentifier.match("0abc_ab"))
- self.assertIsNone(ProtoIdentifier.match("0_ab_0a_a0"))
- self.assertIsNone(ProtoIdentifier.match(" "))
- self.assertIsNone(ProtoIdentifier.match(" abc"))
- self.assertIsNone(ProtoIdentifier.match("\nabc"))
- self.assertIsNone(ProtoIdentifier.match("\n abc"))
- self.assertIsNone(ProtoIdentifier.match("\tabc"))
- self.assertIsNone(ProtoIdentifier.match("\n\tabc"))
- self.assertIsNone(ProtoIdentifier.match("\t\nabc"))
- self.assertIsNone(ProtoIdentifier.match("\t\n abc"))
- self.assertIsNone(ProtoIdentifier.match(".a"))
- self.assertIsNone(ProtoIdentifier.match(" .a"))
- self.assertIsNone(ProtoIdentifier.match("."))
- self.assertIsNone(ProtoIdentifier.match(".0"))
+ self.assertIsNone(ProtoIdentifier.match(None, "0"))
+ self.assertIsNone(ProtoIdentifier.match(None, "0abc_ab"))
+ self.assertIsNone(ProtoIdentifier.match(None, "0_ab_0a_a0"))
+ self.assertIsNone(ProtoIdentifier.match(None, " "))
+ self.assertIsNone(ProtoIdentifier.match(None, " abc"))
+ self.assertIsNone(ProtoIdentifier.match(None, "\nabc"))
+ self.assertIsNone(ProtoIdentifier.match(None, "\n abc"))
+ self.assertIsNone(ProtoIdentifier.match(None, "\tabc"))
+ self.assertIsNone(ProtoIdentifier.match(None, "\n\tabc"))
+ self.assertIsNone(ProtoIdentifier.match(None, "\t\nabc"))
+ self.assertIsNone(ProtoIdentifier.match(None, "\t\n abc"))
+ self.assertIsNone(ProtoIdentifier.match(None, ".a"))
+ self.assertIsNone(ProtoIdentifier.match(None, " .a"))
+ self.assertIsNone(ProtoIdentifier.match(None, "."))
+ self.assertIsNone(ProtoIdentifier.match(None, ".0"))
def test_full_ident(self):
- self.assertEqual(ProtoFullIdentifier.match("a").node.identifier, "a")
- self.assertEqual(ProtoFullIdentifier.match("a.bar").node.identifier, "a.bar")
+ self.assertEqual(ProtoFullIdentifier.match(None, "a").node.identifier, "a")
+ self.assertEqual(
+ ProtoFullIdentifier.match(None, "a.bar").node.identifier, "a.bar"
+ )
self.assertEqual(
- ProtoFullIdentifier.match("a.bar.baz").node.identifier, "a.bar.baz"
+ ProtoFullIdentifier.match(None, "a.bar.baz").node.identifier, "a.bar.baz"
)
self.assertEqual(
- ProtoFullIdentifier.match("a.bar.b0").node.identifier, "a.bar.b0"
+ ProtoFullIdentifier.match(None, "a.bar.b0").node.identifier, "a.bar.b0"
)
self.assertEqual(
- ProtoFullIdentifier.match("a.bar.b0.c_2a").node.identifier, "a.bar.b0.c_2a"
+ ProtoFullIdentifier.match(None, "a.bar.b0.c_2a").node.identifier,
+ "a.bar.b0.c_2a",
)
def test_full_ident_invalid_periods(self):
with self.assertRaises(ValueError):
- ProtoFullIdentifier.match("a.")
+ ProtoFullIdentifier.match(None, "a.")
with self.assertRaises(ValueError):
- ProtoFullIdentifier.match("a.bar.")
+ ProtoFullIdentifier.match(None, "a.bar.")
with self.assertRaises(ValueError):
- ProtoFullIdentifier.match("a..")
+ ProtoFullIdentifier.match(None, "a..")
def test_message_type(self):
- self.assertEqual(ProtoEnumOrMessageIdentifier.match("a").node.identifier, "a")
- self.assertEqual(ProtoEnumOrMessageIdentifier.match(".a").node.identifier, ".a")
self.assertEqual(
- ProtoEnumOrMessageIdentifier.match(".a.bar").node.identifier, ".a.bar"
+ ProtoEnumOrMessageIdentifier.match(None, "a").node.identifier, "a"
+ )
+ self.assertEqual(
+ ProtoEnumOrMessageIdentifier.match(None, ".a").node.identifier, ".a"
+ )
+ self.assertEqual(
+ ProtoEnumOrMessageIdentifier.match(None, ".a.bar").node.identifier, ".a.bar"
)
self.assertEqual(
- ProtoEnumOrMessageIdentifier.match("a.bar").node.identifier, "a.bar"
+ ProtoEnumOrMessageIdentifier.match(None, "a.bar").node.identifier, "a.bar"
)
def test_identifier_serialize(self):
- self.assertEqual(ProtoIdentifier.match("a").node.serialize(), "a")
- self.assertEqual(ProtoIdentifier.match("a0").node.serialize(), "a0")
+ self.assertEqual(ProtoIdentifier.match(None, "a").node.serialize(), "a")
+ self.assertEqual(ProtoIdentifier.match(None, "a0").node.serialize(), "a0")
self.assertEqual(
- ProtoIdentifier.match("a_").node.serialize(),
+ ProtoIdentifier.match(None, "a_").node.serialize(),
"a_",
)
self.assertEqual(
- ProtoIdentifier.match("a0_foo_ba0_0baz").node.serialize(),
+ ProtoIdentifier.match(None, "a0_foo_ba0_0baz").node.serialize(),
"a0_foo_ba0_0baz",
)
self.assertEqual(
- ProtoFullIdentifier.match("a.bar").node.serialize(),
+ ProtoFullIdentifier.match(None, "a.bar").node.serialize(),
"a.bar",
)
self.assertEqual(
- ProtoFullIdentifier.match("a.bar_baz.foo0").node.serialize(),
+ ProtoFullIdentifier.match(None, "a.bar_baz.foo0").node.serialize(),
"a.bar_baz.foo0",
)
self.assertEqual(
- ProtoEnumOrMessageIdentifier.match(".a").node.serialize(),
+ ProtoEnumOrMessageIdentifier.match(None, ".a").node.serialize(),
".a",
)
self.assertEqual(
- ProtoEnumOrMessageIdentifier.match(".a.bar0_baz.foo").node.serialize(),
+ ProtoEnumOrMessageIdentifier.match(
+ None, ".a.bar0_baz.foo"
+ ).node.serialize(),
".a.bar0_baz.foo",
)
diff --git a/test/proto_import_test.py b/test/proto_import_test.py
index 0ea8ffb..994ec22 100644
--- a/test/proto_import_test.py
+++ b/test/proto_import_test.py
@@ -13,14 +13,14 @@
class ImportTest(unittest.TestCase):
def test_bare_import(self):
- double_quote_import = ProtoImport.match('import "foo.proto";')
+ double_quote_import = ProtoImport.match(None, 'import "foo.proto";')
self.assertEqual(double_quote_import.node.path.value, "foo.proto")
self.assertEqual(double_quote_import.node.weak, False)
self.assertEqual(double_quote_import.node.public, False)
self.assertEqual(double_quote_import.node.serialize(), 'import "foo.proto";')
self.assertEqual(double_quote_import.remaining_source, "")
- single_quote_import = ProtoImport.match("import 'foo.proto';")
+ single_quote_import = ProtoImport.match(None, "import 'foo.proto';")
self.assertEqual(single_quote_import.node.path.value, "foo.proto")
self.assertEqual(single_quote_import.node.weak, False)
self.assertEqual(single_quote_import.node.public, False)
@@ -29,29 +29,29 @@ def test_bare_import(self):
def test_import_missing_semicolon(self):
with self.assertRaises(ValueError):
- ProtoImport.match('import "foo.proto"')
+ ProtoImport.match(None, 'import "foo.proto"')
def test_import_missing_starting_quote(self):
with self.assertRaises(ValueError):
- ProtoImport.match('import foo.proto";')
+ ProtoImport.match(None, 'import foo.proto";')
with self.assertRaises(ValueError):
- ProtoImport.match("import foo.proto';")
+ ProtoImport.match(None, "import foo.proto';")
def test_import_missing_ending_quote(self):
with self.assertRaises(ValueError):
- ProtoImport.match('import "foo.proto;')
+ ProtoImport.match(None, 'import "foo.proto;')
with self.assertRaises(ValueError):
- ProtoImport.match("import 'foo.proto;")
+ ProtoImport.match(None, "import 'foo.proto;")
def test_weak_import(self):
- double_quote_import = ProtoImport.match('import weak "foo.proto";')
+ double_quote_import = ProtoImport.match(None, 'import weak "foo.proto";')
self.assertEqual(double_quote_import.node.weak, True)
self.assertEqual(
double_quote_import.node.serialize(), 'import weak "foo.proto";'
)
- double_quote_import = ProtoImport.match("import weak 'foo.proto';")
+ double_quote_import = ProtoImport.match(None, "import weak 'foo.proto';")
self.assertEqual(double_quote_import.node.weak, True)
self.assertEqual(
double_quote_import.node.serialize(), "import weak 'foo.proto';"
@@ -59,40 +59,45 @@ def test_weak_import(self):
def test_weak_typoed_import(self):
with self.assertRaises(ValueError):
- ProtoImport.match('import weac "foo.proto";')
+ ProtoImport.match(None, 'import weac "foo.proto";')
def test_weak_mixed_imports(self):
first_parsed_import = ProtoImport.match(
+ None,
dedent(
"""import "foo.proto";
import weak "bar/baz.proto";
import "bat.proto";"""
- )
+ ),
)
self.assertEqual(first_parsed_import.node.path.value, "foo.proto")
self.assertEqual(first_parsed_import.node.weak, False)
self.assertEqual(first_parsed_import.node.serialize(), 'import "foo.proto";')
- second_parsed_import = ProtoImport.match(first_parsed_import.remaining_source)
+ second_parsed_import = ProtoImport.match(
+ None, first_parsed_import.remaining_source
+ )
self.assertEqual(second_parsed_import.node.path.value, "bar/baz.proto")
self.assertEqual(second_parsed_import.node.weak, True)
self.assertEqual(
second_parsed_import.node.serialize(), 'import weak "bar/baz.proto";'
)
- third_parsed_import = ProtoImport.match(second_parsed_import.remaining_source)
+ third_parsed_import = ProtoImport.match(
+ None, second_parsed_import.remaining_source
+ )
self.assertEqual(third_parsed_import.node.path.value, "bat.proto")
self.assertEqual(third_parsed_import.node.weak, False)
self.assertEqual(third_parsed_import.node.serialize(), 'import "bat.proto";')
def test_public_import(self):
- double_quote_import = ProtoImport.match('import public "foo.proto";')
+ double_quote_import = ProtoImport.match(None, 'import public "foo.proto";')
self.assertEqual(double_quote_import.node.public, True)
self.assertEqual(
double_quote_import.node.serialize(), 'import public "foo.proto";'
)
- single_quote_import = ProtoImport.match("import public 'foo.proto';")
+ single_quote_import = ProtoImport.match(None, "import public 'foo.proto';")
self.assertEqual(single_quote_import.node.public, True)
self.assertEqual(
single_quote_import.node.serialize(), "import public 'foo.proto';"
@@ -100,35 +105,40 @@ def test_public_import(self):
def test_public_typoed_import(self):
with self.assertRaises(ValueError):
- ProtoImport.match('import publik "foo.proto";')
+ ProtoImport.match(None, 'import publik "foo.proto";')
def test_public_weak_mutually_exclusive(self):
with self.assertRaises(ValueError):
- ProtoImport.match('import weak public "foo.proto";')
+ ProtoImport.match(None, 'import weak public "foo.proto";')
with self.assertRaises(ValueError):
- ProtoImport.match('import public weak "foo.proto";')
+ ProtoImport.match(None, 'import public weak "foo.proto";')
def test_public_mixed_imports(self):
first_parsed_import = ProtoImport.match(
+ None,
dedent(
"""import "foo.proto";
import public "bar/baz.proto";
import public "bat.proto";"""
- )
+ ),
)
self.assertEqual(first_parsed_import.node.path.value, "foo.proto")
self.assertEqual(first_parsed_import.node.public, False)
self.assertEqual(first_parsed_import.node.serialize(), 'import "foo.proto";')
- second_parsed_import = ProtoImport.match(first_parsed_import.remaining_source)
+ second_parsed_import = ProtoImport.match(
+ None, first_parsed_import.remaining_source
+ )
self.assertEqual(second_parsed_import.node.path.value, "bar/baz.proto")
self.assertEqual(second_parsed_import.node.public, True)
self.assertEqual(
second_parsed_import.node.serialize(), 'import public "bar/baz.proto";'
)
- third_parsed_import = ProtoImport.match(second_parsed_import.remaining_source)
+ third_parsed_import = ProtoImport.match(
+ None, second_parsed_import.remaining_source
+ )
self.assertEqual(third_parsed_import.node.path.value, "bat.proto")
self.assertEqual(third_parsed_import.node.public, True)
self.assertEqual(
@@ -136,21 +146,21 @@ def test_public_mixed_imports(self):
)
def test_diff_sets_same_path_simple(self):
- pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
- pf2 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ pf1 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
+ pf2 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
self.assertEqual(ProtoImport.diff_sets([pf1], [pf2]), [])
def test_diff_sets_added_path_simple(self):
- pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ pf1 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
self.assertEqual(ProtoImport.diff_sets([pf1], []), [ProtoImportAdded(pf1)])
def test_diff_sets_removed_path_simple(self):
- pf2 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ pf2 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
self.assertEqual(ProtoImport.diff_sets([], [pf2]), [ProtoImportRemoved(pf2)])
def test_diff_sets_different_path_simple(self):
- pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
- pf2 = ProtoImport(ProtoStringLiteral("path/to/some/other.proto"))
+ pf1 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
+ pf2 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some/other.proto"))
self.assertEqual(
ProtoImport.diff_sets([pf1], [pf2]),
[ProtoImportAdded(pf1), ProtoImportRemoved(pf2)],
@@ -158,10 +168,16 @@ def test_diff_sets_different_path_simple(self):
def test_diff_sets_changed_optional_attributes(self):
pf1 = ProtoImport(
- ProtoStringLiteral("path/to/some.proto"), weak=False, public=True
+ None,
+ ProtoStringLiteral(None, "path/to/some.proto"),
+ weak=False,
+ public=True,
)
pf2 = ProtoImport(
- ProtoStringLiteral("path/to/some.proto"), weak=True, public=False
+ None,
+ ProtoStringLiteral(None, "path/to/some.proto"),
+ weak=True,
+ public=False,
)
self.assertEqual(
ProtoImport.diff_sets([pf1], [pf2]),
diff --git a/test/proto_int_test.py b/test/proto_int_test.py
index 3293d5e..0aaf7f7 100644
--- a/test/proto_int_test.py
+++ b/test/proto_int_test.py
@@ -5,31 +5,33 @@
class IntTest(unittest.TestCase):
def test_int(self):
- self.assertEqual(ProtoInt.match("1").node, ProtoInt(1, ProtoIntSign.POSITIVE))
self.assertEqual(
- ProtoInt.match("158912938471293847").node,
- ProtoInt(158912938471293847, ProtoIntSign.POSITIVE),
+ ProtoInt.match(None, "1").node, ProtoInt(None, 1, ProtoIntSign.POSITIVE)
+ )
+ self.assertEqual(
+ ProtoInt.match(None, "158912938471293847").node,
+ ProtoInt(None, 158912938471293847, ProtoIntSign.POSITIVE),
)
def test_octal(self):
self.assertEqual(
- ProtoInt.match("072342").node,
- ProtoInt(0o72342, ProtoIntSign.POSITIVE),
+ ProtoInt.match(None, "072342").node,
+ ProtoInt(None, 0o72342, ProtoIntSign.POSITIVE),
)
with self.assertRaises(ValueError):
- ProtoInt.match("072942")
+ ProtoInt.match(None, "072942")
def test_hex(self):
self.assertEqual(
- ProtoInt.match("0x72342").node,
- ProtoInt(0x72342, ProtoIntSign.POSITIVE),
+ ProtoInt.match(None, "0x72342").node,
+ ProtoInt(None, 0x72342, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoInt.match("0x7A3d2").node,
- ProtoInt(0x7A3D2, ProtoIntSign.POSITIVE),
+ ProtoInt.match(None, "0x7A3d2").node,
+ ProtoInt(None, 0x7A3D2, ProtoIntSign.POSITIVE),
)
with self.assertRaises(ValueError):
- ProtoInt.match("0x72G42")
+ ProtoInt.match(None, "0x72G42")
if __name__ == "__main__":
diff --git a/test/proto_message_field_test.py b/test/proto_message_field_test.py
index 8692322..eb64ca3 100644
--- a/test/proto_message_field_test.py
+++ b/test/proto_message_field_test.py
@@ -13,13 +13,14 @@ class MessageFieldTest(unittest.TestCase):
maxDiff = None
def test_field_optional_default_false(self):
- string_field = ProtoMessageField.match("string single_field = 1;")
+ string_field = ProtoMessageField.match(None, "string single_field = 1;")
self.assertEqual(
string_field.node,
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("single_field"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "single_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
False,
False,
),
@@ -27,14 +28,15 @@ def test_field_optional_default_false(self):
def test_field_optional_set(self):
string_field = ProtoMessageField.match(
- "optional string single_field = 1;".strip()
+ None, "optional string single_field = 1;".strip()
)
self.assertEqual(
string_field.node,
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("single_field"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "single_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
False,
True,
),
@@ -43,77 +45,85 @@ def test_field_optional_set(self):
def test_field_cannot_have_repeated_and_optional(self):
with self.assertRaises(ValueError):
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("single_field"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "single_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
True,
True,
)
def test_message_field_starts_with_underscore(self):
- parsed_undescored_field = ProtoMessageField.match("string _test_field = 1;")
+ parsed_undescored_field = ProtoMessageField.match(
+ None, "string _test_field = 1;"
+ )
self.assertEqual(
parsed_undescored_field.node,
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("_test_field"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "_test_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
)
parsed_double_undescored_field = ProtoMessageField.match(
- "bool __test_field = 1;"
+ None, "bool __test_field = 1;"
)
self.assertEqual(
parsed_double_undescored_field.node,
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("__test_field"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "__test_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
)
def test_field_repeated(self):
parsed_message_with_repeated_field_simple = ProtoMessageField.match(
- "repeated bool repeated_field = 3;"
+ None, "repeated bool repeated_field = 3;"
)
self.assertEqual(
parsed_message_with_repeated_field_simple.node,
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.BOOL,
- ProtoIdentifier("repeated_field"),
- ProtoInt(3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "repeated_field"),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
True,
),
)
def test_field_enum_or_message(self):
parsed_message_with_repeated_field_simple = ProtoMessageField.match(
- "foo.SomeEnumOrMessage enum_or_message_field = 1;"
+ None, "foo.SomeEnumOrMessage enum_or_message_field = 1;"
)
self.assertEqual(
parsed_message_with_repeated_field_simple.node,
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("enum_or_message_field"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "enum_or_message_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier("foo.SomeEnumOrMessage"),
+ ProtoFullIdentifier(None, "foo.SomeEnumOrMessage"),
),
)
def test_field_starts_with_period(self):
parsed_field_with_type_starting_with_period = ProtoMessageField.match(
- ".google.proto.FooType enum_or_message_field = 1;"
+ None, ".google.proto.FooType enum_or_message_field = 1;"
)
self.assertEqual(
parsed_field_with_type_starting_with_period.node,
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("enum_or_message_field"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "enum_or_message_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
False,
False,
- ProtoEnumOrMessageIdentifier(".google.proto.FooType"),
+ ProtoEnumOrMessageIdentifier(None, ".google.proto.FooType"),
),
)
diff --git a/test/proto_message_test.py b/test/proto_message_test.py
index 0812498..3153c72 100644
--- a/test/proto_message_test.py
+++ b/test/proto_message_test.py
@@ -38,6 +38,7 @@ class MessageTest(unittest.TestCase):
def test_message_all_features(self):
parsed_message_multiple_fields = ProtoMessage.match(
+ None,
dedent(
"""
message FooMessage {
@@ -63,125 +64,158 @@ def test_message_all_features(self):
extensions 8 to max;
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_message_multiple_fields.node.nodes,
[
ProtoOption(
- ProtoIdentifier("(foo.bar).baz"),
- ProtoConstant(ProtoStringLiteral("bat")),
+ None,
+ ProtoIdentifier(None, "(foo.bar).baz"),
+ ProtoConstant(None, ProtoStringLiteral(None, "bat")),
),
ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_UNDEFINED"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "ME_UNDEFINED"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- ProtoIdentifier("ME_VALONE"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "ME_VALONE"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- ProtoIdentifier("ME_VALTWO"),
- ProtoInt(2, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "ME_VALTWO"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
),
],
),
- ProtoMessage(ProtoIdentifier("NestedMessage"), []),
- ProtoReserved(fields=[ProtoIdentifier("a")]),
+ ProtoMessage(None, ProtoIdentifier(None, "NestedMessage"), []),
+ ProtoReserved(None, fields=[ProtoIdentifier(None, "a")]),
ProtoReserved(
+ None,
ranges=[
ProtoRange(
- ProtoInt(1, ProtoIntSign.POSITIVE),
- ProtoInt(3, ProtoIntSign.POSITIVE),
+ None,
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
)
- ]
+ ],
),
- ProtoSingleLineComment(" single-line comment"),
+ ProtoSingleLineComment(None, " single-line comment"),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("some_field"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "some_field"),
+ ProtoInt(None, 4, ProtoIntSign.POSITIVE),
True,
False,
None,
[
ProtoMessageFieldOption(
- ProtoIdentifier("(bar.baz).bat"),
- ProtoConstant(ProtoStringLiteral("bat")),
+ None,
+ ProtoIdentifier(None, "(bar.baz).bat"),
+ ProtoConstant(None, ProtoStringLiteral(None, "bat")),
),
ProtoMessageFieldOption(
- ProtoIdentifier("baz.bat"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
+ None,
+ ProtoIdentifier(None, "baz.bat"),
+ ProtoConstant(
+ None, ProtoInt(None, 100, ProtoIntSign.NEGATIVE)
+ ),
),
],
),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.BOOL,
- ProtoIdentifier("some_bool_field"),
- ProtoInt(5, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "some_bool_field"),
+ ProtoInt(None, 5, ProtoIntSign.POSITIVE),
),
ProtoOneOf(
- ProtoIdentifier("one_of_field"),
+ None,
+ ProtoIdentifier(None, "one_of_field"),
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "name"),
+ ProtoInt(None, 4, ProtoIntSign.POSITIVE),
),
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(
+ None, ProtoStringLiteral(None, "com.example.foo")
+ ),
),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("sub_message"),
- ProtoInt(9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "sub_message"),
+ ProtoInt(None, 9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier("SubMessage"),
+ ProtoFullIdentifier(None, "SubMessage"),
[
ProtoMessageFieldOption(
- ProtoIdentifier("(bar.baz).bat"),
- ProtoConstant(ProtoStringLiteral("bat")),
+ None,
+ ProtoIdentifier(None, "(bar.baz).bat"),
+ ProtoConstant(
+ None, ProtoStringLiteral(None, "bat")
+ ),
),
ProtoMessageFieldOption(
- ProtoIdentifier("baz.bat"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
+ None,
+ ProtoIdentifier(None, "baz.bat"),
+ ProtoConstant(
+ None, ProtoInt(None, 100, ProtoIntSign.NEGATIVE)
+ ),
),
],
),
],
),
ProtoMap(
+ None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("my_map"),
- ProtoInt(10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier("NestedMessage"),
+ ProtoIdentifier(None, "my_map"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
[],
),
ProtoMap(
+ None,
# map string_map = 11 [ java_package = "com.example.foo", baz.bat = 48 ];
ProtoMapKeyTypesEnum.STRING,
ProtoMapValueTypesEnum.STRING,
- ProtoIdentifier("string_map"),
- ProtoInt(11, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "string_map"),
+ ProtoInt(None, 11, ProtoIntSign.POSITIVE),
None,
[
ProtoMessageFieldOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(
+ None, ProtoStringLiteral(None, "com.example.foo")
+ ),
),
ProtoMessageFieldOption(
- ProtoFullIdentifier("baz.bat"),
- ProtoConstant(ProtoInt(48, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoFullIdentifier(None, "baz.bat"),
+ ProtoConstant(
+ None, ProtoInt(None, 48, ProtoIntSign.POSITIVE)
+ ),
),
],
),
- ProtoExtensions([ProtoRange(8, ProtoRangeEnum.MAX)]),
+ ProtoExtensions(None, [ProtoRange(None, 8, ProtoRangeEnum.MAX)]),
],
)
self.assertEqual(
@@ -216,24 +250,30 @@ def test_message_all_features(self):
)
def test_empty_message(self):
- parsed_empty_message = ProtoMessage.match("""message FooMessage {}""")
+ parsed_empty_message = ProtoMessage.match(None, """message FooMessage {}""")
self.assertIsNotNone(parsed_empty_message)
- self.assertEqual(parsed_empty_message.node.name, ProtoIdentifier("FooMessage"))
+ self.assertEqual(
+ parsed_empty_message.node.name, ProtoIdentifier(None, "FooMessage")
+ )
parsed_spaced_message = ProtoMessage.match(
+ None,
dedent(
"""
message FooMessage {
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(parsed_spaced_message)
- self.assertEqual(parsed_spaced_message.node.name, ProtoIdentifier("FooMessage"))
+ self.assertEqual(
+ parsed_spaced_message.node.name, ProtoIdentifier(None, "FooMessage")
+ )
def test_message_empty_statements(self):
empty_statement_message = ProtoMessage.match(
+ None,
dedent(
"""
message FooMessage {
@@ -241,15 +281,16 @@ def test_message_empty_statements(self):
;
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(empty_statement_message)
self.assertEqual(
- empty_statement_message.node.name, ProtoIdentifier("FooMessage")
+ empty_statement_message.node.name, ProtoIdentifier(None, "FooMessage")
)
def test_message_optionals(self):
parsed_message_with_optionals = ProtoMessage.match(
+ None,
dedent(
"""
message FooMessage {
@@ -257,27 +298,30 @@ def test_message_optionals(self):
option (foo.bar).baz = false;
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(
parsed_message_with_optionals.node.options,
[
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foobar")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foobar")),
),
ProtoOption(
- ProtoIdentifier("(foo.bar).baz"),
- ProtoConstant(ProtoBool(False)),
+ None,
+ ProtoIdentifier(None, "(foo.bar).baz"),
+ ProtoConstant(None, ProtoBool(None, False)),
),
],
)
self.assertEqual(
- parsed_message_with_optionals.node.name, ProtoIdentifier("FooMessage")
+ parsed_message_with_optionals.node.name, ProtoIdentifier(None, "FooMessage")
)
def test_message_nested_enum(self):
parsed_message_with_enum = ProtoMessage.match(
+ None,
dedent(
"""
message FooMessage {
@@ -288,27 +332,32 @@ def test_message_nested_enum(self):
}
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_message_with_enum.node,
ProtoMessage(
- ProtoIdentifier("FooMessage"),
+ None,
+ ProtoIdentifier(None, "FooMessage"),
[
ProtoEnum(
- ProtoIdentifier("MyEnum"),
+ None,
+ ProtoIdentifier(None, "MyEnum"),
[
ProtoEnumValue(
- ProtoIdentifier("ME_UNDEFINED"),
- ProtoInt(0, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "ME_UNDEFINED"),
+ ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- ProtoIdentifier("ME_NEGATIVE"),
- ProtoInt(1, ProtoIntSign.NEGATIVE),
+ None,
+ ProtoIdentifier(None, "ME_NEGATIVE"),
+ ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
),
ProtoEnumValue(
- ProtoIdentifier("ME_VALONE"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ None,
+ ProtoIdentifier(None, "ME_VALONE"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
],
)
@@ -318,26 +367,29 @@ def test_message_nested_enum(self):
def test_message_nested_message(self):
parsed_message_with_enum = ProtoMessage.match(
+ None,
dedent(
"""
message FooMessage {
message NestedMessage {}
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_message_with_enum.node,
ProtoMessage(
- ProtoIdentifier("FooMessage"),
+ None,
+ ProtoIdentifier(None, "FooMessage"),
[
- ProtoMessage(ProtoIdentifier("NestedMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "NestedMessage"), []),
],
),
)
def test_message_reserved_single_field(self):
parsed_message_with_reserved_single_field = ProtoMessage.match(
+ None,
dedent(
"""
message FooMessage {
@@ -345,31 +397,36 @@ def test_message_reserved_single_field(self):
reserved "foo", "barBaz";
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_message_with_reserved_single_field.node,
ProtoMessage(
- ProtoIdentifier("FooMessage"),
+ None,
+ ProtoIdentifier(None, "FooMessage"),
[
ProtoReserved(
+ None,
ranges=[
- ProtoRange(ProtoInt(38, ProtoIntSign.POSITIVE)),
+ ProtoRange(None, ProtoInt(None, 38, ProtoIntSign.POSITIVE)),
ProtoRange(
- ProtoInt(48, ProtoIntSign.POSITIVE),
- ProtoInt(100, ProtoIntSign.POSITIVE),
+ None,
+ ProtoInt(None, 48, ProtoIntSign.POSITIVE),
+ ProtoInt(None, 100, ProtoIntSign.POSITIVE),
),
ProtoRange(
- ProtoInt(72, ProtoIntSign.POSITIVE),
+ None,
+ ProtoInt(None, 72, ProtoIntSign.POSITIVE),
ProtoRangeEnum.MAX,
),
- ]
+ ],
),
ProtoReserved(
+ None,
fields=[
- ProtoIdentifier("foo"),
- ProtoIdentifier("barBaz"),
- ]
+ ProtoIdentifier(None, "foo"),
+ ProtoIdentifier(None, "barBaz"),
+ ],
),
],
),
@@ -377,81 +434,93 @@ def test_message_reserved_single_field(self):
def test_message_simple_field(self):
parsed_message_with_single_field_simple = ProtoMessage.match(
+ None,
dedent(
"""
message FooMessage {
string single_field = 1;
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_message_with_single_field_simple.node,
ProtoMessage(
- ProtoIdentifier("FooMessage"),
+ None,
+ ProtoIdentifier(None, "FooMessage"),
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("single_field"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "single_field"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
)
],
),
)
def test_oneof_empty(self):
- parsed_oneof_empty = ProtoOneOf.match(dedent("oneof one_of_field {}".strip()))
+ parsed_oneof_empty = ProtoOneOf.match(
+ None, dedent("oneof one_of_field {}".strip())
+ )
self.assertEqual(
parsed_oneof_empty.node,
ProtoOneOf(
- ProtoIdentifier("one_of_field"),
+ None,
+ ProtoIdentifier(None, "one_of_field"),
[],
),
)
def test_oneof_empty_statements(self):
parsed_oneof_empty = ProtoOneOf.match(
+ None,
dedent(
"""oneof one_of_field {
;
;
}""".strip()
- )
+ ),
)
self.assertEqual(
parsed_oneof_empty.node,
ProtoOneOf(
- ProtoIdentifier("one_of_field"),
+ None,
+ ProtoIdentifier(None, "one_of_field"),
[],
),
)
def test_oneof_basic_fields(self):
parsed_oneof_basic_fields = ProtoOneOf.match(
+ None,
dedent(
"""oneof one_of_field {
string name = 4;
SubMessage sub_message = 9;
}""".strip()
- )
+ ),
)
self.assertEqual(
parsed_oneof_basic_fields.node,
ProtoOneOf(
- ProtoIdentifier("one_of_field"),
+ None,
+ ProtoIdentifier(None, "one_of_field"),
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "name"),
+ ProtoInt(None, 4, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("sub_message"),
- ProtoInt(9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "sub_message"),
+ ProtoInt(None, 9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier("SubMessage"),
+ ProtoFullIdentifier(None, "SubMessage"),
[],
),
],
@@ -460,20 +529,25 @@ def test_oneof_basic_fields(self):
def test_oneof_options(self):
parsed_oneof_options = ProtoOneOf.match(
+ None,
dedent(
"""oneof one_of_field {
option java_package = "com.example.foo";
}""".strip()
- )
+ ),
)
self.assertEqual(
parsed_oneof_options.node,
ProtoOneOf(
- ProtoIdentifier("one_of_field"),
+ None,
+ ProtoIdentifier(None, "one_of_field"),
[
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(
+ None, ProtoStringLiteral(None, "com.example.foo")
+ ),
),
],
),
@@ -481,32 +555,39 @@ def test_oneof_options(self):
def test_oneof_field_option(self):
parsed_oneof_field_option = ProtoOneOf.match(
+ None,
dedent(
"""oneof one_of_field {
string name = 4 [ (bar.baz).bat = "bat", baz.bat = -100 ];
}""".strip()
- )
+ ),
)
self.assertEqual(
parsed_oneof_field_option.node,
ProtoOneOf(
- ProtoIdentifier("one_of_field"),
+ None,
+ ProtoIdentifier(None, "one_of_field"),
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "name"),
+ ProtoInt(None, 4, ProtoIntSign.POSITIVE),
False,
False,
None,
[
ProtoMessageFieldOption(
- ProtoIdentifier("(bar.baz).bat"),
- ProtoConstant(ProtoStringLiteral("bat")),
+ None,
+ ProtoIdentifier(None, "(bar.baz).bat"),
+ ProtoConstant(None, ProtoStringLiteral(None, "bat")),
),
ProtoMessageFieldOption(
- ProtoIdentifier("baz.bat"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
+ None,
+ ProtoIdentifier(None, "baz.bat"),
+ ProtoConstant(
+ None, ProtoInt(None, 100, ProtoIntSign.NEGATIVE)
+ ),
),
],
)
@@ -516,32 +597,36 @@ def test_oneof_field_option(self):
def test_oneof_with_comment(self):
parsed_oneof_with_comment = ProtoOneOf.match(
+ None,
dedent(
"""oneof one_of_field {
string name = 4;
// single-line comment!
SubMessage sub_message = 9;
}""".strip()
- )
+ ),
)
self.assertEqual(
parsed_oneof_with_comment.node,
ProtoOneOf(
- ProtoIdentifier("one_of_field"),
+ None,
+ ProtoIdentifier(None, "one_of_field"),
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "name"),
+ ProtoInt(None, 4, ProtoIntSign.POSITIVE),
),
- ProtoSingleLineComment(" single-line comment!"),
+ ProtoSingleLineComment(None, " single-line comment!"),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("sub_message"),
- ProtoInt(9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "sub_message"),
+ ProtoInt(None, 9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier("SubMessage"),
+ ProtoFullIdentifier(None, "SubMessage"),
[],
),
],
@@ -550,101 +635,116 @@ def test_oneof_with_comment(self):
def test_oneof_normalize_removes_comment(self):
normalized_oneof = ProtoOneOf.match(
+ None,
dedent(
"""oneof one_of_field {
string name = 4;
// single-line comment!
SubMessage sub_message = 9;
}""".strip()
- )
+ ),
).node.normalize()
self.assertEqual(
normalized_oneof.nodes,
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "name"),
+ ProtoInt(None, 4, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("sub_message"),
- ProtoInt(9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "sub_message"),
+ ProtoInt(None, 9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier("SubMessage"),
+ ProtoFullIdentifier(None, "SubMessage"),
[],
),
],
)
def test_simple_map(self):
- parsed_map_simple = ProtoMap.match("map my_map = 10;")
+ parsed_map_simple = ProtoMap.match(
+ None, "map my_map = 10;"
+ )
self.assertEqual(
parsed_map_simple.node,
ProtoMap(
+ None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("my_map"),
- ProtoInt(10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier("NestedMessage"),
+ ProtoIdentifier(None, "my_map"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
[],
),
)
def test_map_without_spaces(self):
- map_without_spaces = ProtoMap.match("map my_map = 10;")
+ map_without_spaces = ProtoMap.match(
+ None, "map my_map = 10;"
+ )
self.assertEqual(
map_without_spaces.node,
ProtoMap(
+ None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("my_map"),
- ProtoInt(10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier("NestedMessage"),
+ ProtoIdentifier(None, "my_map"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
[],
),
)
def test_map_with_options(self):
parsed_map_simple = ProtoMap.match(
- "map my_map = 10 [ java_package = 'com.example.foo', baz.bat = 48 ];"
+ None,
+ "map my_map = 10 [ java_package = 'com.example.foo', baz.bat = 48 ];",
)
self.assertEqual(parsed_map_simple.node.key_type, ProtoMapKeyTypesEnum.SFIXED64)
self.assertEqual(
parsed_map_simple.node.value_type, ProtoMapValueTypesEnum.ENUM_OR_MESSAGE
)
- self.assertEqual(parsed_map_simple.node.name, ProtoIdentifier("my_map"))
+ self.assertEqual(parsed_map_simple.node.name, ProtoIdentifier(None, "my_map"))
self.assertEqual(
- parsed_map_simple.node.number, ProtoInt(10, ProtoIntSign.POSITIVE)
+ parsed_map_simple.node.number, ProtoInt(None, 10, ProtoIntSign.POSITIVE)
)
self.assertEqual(
parsed_map_simple.node.enum_or_message_type_name,
- ProtoEnumOrMessageIdentifier("NestedMessage"),
+ ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
)
self.assertEqual(
parsed_map_simple.node.options,
[
ProtoMessageFieldOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "com.example.foo")),
),
ProtoMessageFieldOption(
- ProtoFullIdentifier("baz.bat"),
- ProtoConstant(ProtoInt(48, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoFullIdentifier(None, "baz.bat"),
+ ProtoConstant(None, ProtoInt(None, 48, ProtoIntSign.POSITIVE)),
),
],
)
def test_map_message_value(self):
- parsed_map_simple = ProtoMap.match("map string_map = 11;")
+ parsed_map_simple = ProtoMap.match(
+ None, "map string_map = 11;"
+ )
self.assertEqual(
parsed_map_simple.node,
ProtoMap(
+ None,
ProtoMapKeyTypesEnum.STRING,
ProtoMapValueTypesEnum.STRING,
- ProtoIdentifier("string_map"),
- ProtoInt(11, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "string_map"),
+ ProtoInt(None, 11, ProtoIntSign.POSITIVE),
None,
[],
),
@@ -652,6 +752,7 @@ def test_map_message_value(self):
def test_message_parses_comments(self):
parsed_comments = ProtoMessage.match(
+ None,
dedent(
"""
message MyMessage {
@@ -666,35 +767,40 @@ def test_message_parses_comments(self):
string baz = 3;
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_comments.node.nodes,
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("foo"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
- ProtoSingleLineComment(" single-line comment!"),
+ ProtoSingleLineComment(None, " single-line comment!"),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.BOOL,
- ProtoIdentifier("bar"),
- ProtoInt(2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "bar"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
),
ProtoMultiLineComment(
- "\n multiple\n line\n comment!\n "
+ None,
+ "\n multiple\n line\n comment!\n ",
),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("baz"),
- ProtoInt(3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "baz"),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
),
],
)
def test_message_extends(self):
parsed_extends = ProtoMessage.match(
+ None,
dedent(
"""
message MyMessage {
@@ -704,21 +810,26 @@ def test_message_extends(self):
}
}
""".strip()
- )
+ ),
)
self.assertEqual(
parsed_extends.node.nodes,
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("foo"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
ProtoExtend(
- ProtoEnumOrMessageIdentifier("SomeOtherMessage"),
+ None,
+ ProtoEnumOrMessageIdentifier(None, "SomeOtherMessage"),
[
ProtoMessageField(
- ProtoMessageFieldTypesEnum.STRING, ProtoIdentifier("foo"), 2
+ None,
+ ProtoMessageFieldTypesEnum.STRING,
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
)
],
),
@@ -727,6 +838,7 @@ def test_message_extends(self):
def test_message_normalizes_away_comments(self):
parsed_comments = ProtoMessage.match(
+ None,
dedent(
"""
message MyMessage {
@@ -741,68 +853,79 @@ def test_message_normalizes_away_comments(self):
string baz = 3;
}
""".strip()
- )
+ ),
).node.normalize()
self.assertEqual(
parsed_comments.nodes,
[
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("foo"),
- ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.BOOL,
- ProtoIdentifier("bar"),
- ProtoInt(2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "bar"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
+ None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("baz"),
- ProtoInt(3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier(None, "baz"),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
),
],
)
def test_diff_same_message_returns_empty(self):
pm1 = ProtoMessage(
- ProtoIdentifier("MyMessage"),
+ None,
+ ProtoIdentifier(None, "MyMessage"),
[],
)
pm2 = ProtoMessage(
- ProtoIdentifier("MyMessage"),
+ None,
+ ProtoIdentifier(None, "MyMessage"),
[],
)
self.assertEqual(ProtoMessage.diff(pm1, pm2), [])
def test_diff_different_message_name_returns_empty(self):
pm1 = ProtoMessage(
- ProtoIdentifier("MyMessage"),
+ None,
+ ProtoIdentifier(None, "MyMessage"),
[],
)
pm2 = ProtoMessage(
- ProtoIdentifier("OtherMessage"),
+ None,
+ ProtoIdentifier(None, "OtherMessage"),
[],
)
self.assertEqual(ProtoMessage.diff(pm1, pm2), [])
def test_diff_enum_added(self):
pm1 = None
- pm2 = ProtoMessage(ProtoIdentifier("MyMessage"), [])
+ pm2 = ProtoMessage(None, ProtoIdentifier(None, "MyMessage"), [])
self.assertEqual(
ProtoMessage.diff(pm1, pm2),
[
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("MyMessage"), [])),
+ ProtoMessageAdded(
+ ProtoMessage(None, ProtoIdentifier(None, "MyMessage"), [])
+ ),
],
)
def test_diff_message_removed(self):
- pm1 = ProtoMessage(ProtoIdentifier("MyMessage"), [])
+ pm1 = ProtoMessage(None, ProtoIdentifier(None, "MyMessage"), [])
pm2 = None
self.assertEqual(
ProtoMessage.diff(pm1, pm2),
[
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("MyMessage"), [])),
+ ProtoMessageRemoved(
+ ProtoMessage(None, ProtoIdentifier(None, "MyMessage"), [])
+ ),
],
)
@@ -813,107 +936,155 @@ def test_diff_sets_empty_returns_empty(self):
def test_diff_sets_no_change_returns_empty(self):
set1 = [
- ProtoMessage(ProtoIdentifier("FooMessage"), []),
- ProtoMessage(ProtoIdentifier("BarMessage"), []),
- ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
]
self.assertEqual(ProtoMessage.diff_sets(set1, set1), [])
def test_diff_sets_all_removed(self):
set1 = []
set2 = [
- ProtoMessage(ProtoIdentifier("FooMessage"), []),
- ProtoMessage(ProtoIdentifier("BarMessage"), []),
- ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
]
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage"), [])), diff
+ ProtoMessageRemoved(
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BarMessage"), [])), diff
+ ProtoMessageRemoved(
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage"), [])), diff
+ ProtoMessageRemoved(
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
+ ),
+ diff,
)
self.assertEqual(3, len(diff))
def test_diff_sets_all_added(self):
set1 = [
- ProtoMessage(ProtoIdentifier("FooMessage"), []),
- ProtoMessage(ProtoIdentifier("BarMessage"), []),
- ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
]
set2 = []
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage"), [])), diff
+ ProtoMessageAdded(
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BarMessage"), [])), diff
+ ProtoMessageAdded(
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage"), [])), diff
+ ProtoMessageAdded(
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
+ ),
+ diff,
)
self.assertEqual(3, len(diff))
def test_diff_sets_mutually_exclusive(self):
set1 = [
- ProtoMessage(ProtoIdentifier("FooMessage"), []),
- ProtoMessage(ProtoIdentifier("BarMessage"), []),
- ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
]
set2 = [
- ProtoMessage(ProtoIdentifier("FooMessage2"), []),
- ProtoMessage(ProtoIdentifier("BarMessage2"), []),
- ProtoMessage(ProtoIdentifier("BazMessage2"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage2"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), []),
]
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage"), [])), diff
+ ProtoMessageAdded(
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BarMessage"), [])), diff
+ ProtoMessageAdded(
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage"), [])), diff
+ ProtoMessageAdded(
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage2"), [])), diff
+ ProtoMessageRemoved(
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BarMessage2"), [])), diff
+ ProtoMessageRemoved(
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage2"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage2"), [])), diff
+ ProtoMessageRemoved(
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), [])
+ ),
+ diff,
)
self.assertEqual(6, len(diff))
def test_diff_sets_overlap(self):
set1 = [
- ProtoMessage(ProtoIdentifier("FooMessage"), []),
- ProtoMessage(ProtoIdentifier("BarMessage"), []),
- ProtoMessage(ProtoIdentifier("BazMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
]
set2 = [
- ProtoMessage(ProtoIdentifier("FooMessage2"), []),
- ProtoMessage(ProtoIdentifier("BarMessage"), []),
- ProtoMessage(ProtoIdentifier("BazMessage2"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), []),
]
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage"), [])), diff
+ ProtoMessageAdded(
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage"), [])), diff
+ ProtoMessageAdded(
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage2"), [])), diff
+ ProtoMessageRemoved(
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), [])
+ ),
+ diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage2"), [])), diff
+ ProtoMessageRemoved(
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), [])
+ ),
+ diff,
)
self.assertEqual(4, len(diff))
diff --git a/test/proto_option_test.py b/test/proto_option_test.py
index caf20ed..b1f4ff1 100644
--- a/test/proto_option_test.py
+++ b/test/proto_option_test.py
@@ -19,225 +19,245 @@ class OptionTest(unittest.TestCase):
maxDiff = None
def test_string_option(self):
- string_option = ProtoOption.match("option foo = 'test value';")
- self.assertEqual(string_option.node.name, ProtoIdentifier("foo"))
+ string_option = ProtoOption.match(None, "option foo = 'test value';")
+ self.assertEqual(string_option.node.name, ProtoIdentifier(None, "foo"))
self.assertEqual(
- string_option.node.value.value, ProtoStringLiteral("test value")
+ string_option.node.value.value, ProtoStringLiteral(None, "test value")
)
self.assertEqual(string_option.remaining_source, "")
- string_option = ProtoOption.match('option foo = "test value";')
- self.assertEqual(string_option.node.name, ProtoIdentifier("foo"))
+ string_option = ProtoOption.match(None, 'option foo = "test value";')
+ self.assertEqual(string_option.node.name, ProtoIdentifier(None, "foo"))
self.assertEqual(
- string_option.node.value.value, ProtoStringLiteral("test value")
+ string_option.node.value.value, ProtoStringLiteral(None, "test value")
)
self.assertEqual(string_option.remaining_source, "")
def test_packaged_name(self):
- packaged_option = ProtoOption.match("option foo.bar.baz = 'test value';")
- self.assertEqual(packaged_option.node.name, ProtoFullIdentifier("foo.bar.baz"))
+ packaged_option = ProtoOption.match(None, "option foo.bar.baz = 'test value';")
self.assertEqual(
- packaged_option.node.value.value, ProtoStringLiteral("test value")
+ packaged_option.node.name, ProtoFullIdentifier(None, "foo.bar.baz")
+ )
+ self.assertEqual(
+ packaged_option.node.value.value, ProtoStringLiteral(None, "test value")
)
def test_parenthesized_name(self):
- parenthesized_option = ProtoOption.match("option (foo) = 'test value';")
- self.assertEqual(parenthesized_option.node.name, ProtoIdentifier("(foo)"))
+ parenthesized_option = ProtoOption.match(None, "option (foo) = 'test value';")
+ self.assertEqual(parenthesized_option.node.name, ProtoIdentifier(None, "(foo)"))
self.assertEqual(
- parenthesized_option.node.value.value, ProtoStringLiteral("test value")
+ parenthesized_option.node.value.value,
+ ProtoStringLiteral(None, "test value"),
)
fully_qualified_name_option = ProtoOption.match(
- "option (foo).bar.baz = 'test value';"
+ None, "option (foo).bar.baz = 'test value';"
)
self.assertEqual(
- fully_qualified_name_option.node.name, ProtoFullIdentifier("(foo).bar.baz")
+ fully_qualified_name_option.node.name,
+ ProtoFullIdentifier(None, "(foo).bar.baz"),
)
self.assertEqual(
fully_qualified_name_option.node.value.value,
- ProtoStringLiteral("test value"),
+ ProtoStringLiteral(None, "test value"),
)
def test_string_option_missing_semicolon(self):
with self.assertRaises(ValueError):
- ProtoOption.match("option foo = 'test value'")
+ ProtoOption.match(None, "option foo = 'test value'")
with self.assertRaises(ValueError):
- ProtoOption.match('option foo = "test value"')
+ ProtoOption.match(None, 'option foo = "test value"')
def test_string_option_missing_quote(self):
with self.assertRaises(ValueError):
- ProtoOption.match("option foo = test value;")
+ ProtoOption.match(None, "option foo = test value;")
with self.assertRaises(ValueError):
- ProtoOption.match("option foo = 'test value;")
+ ProtoOption.match(None, "option foo = 'test value;")
with self.assertRaises(ValueError):
- ProtoOption.match('option foo = "test value;')
+ ProtoOption.match(None, 'option foo = "test value;')
with self.assertRaises(ValueError):
- ProtoOption.match("option foo = test value';")
+ ProtoOption.match(None, "option foo = test value';")
with self.assertRaises(ValueError):
- ProtoOption.match('option foo = test value";')
+ ProtoOption.match(None, 'option foo = test value";')
with self.assertRaises(ValueError):
- ProtoOption.match("option foo = 'test value\";")
+ ProtoOption.match(None, "option foo = 'test value\";")
with self.assertRaises(ValueError):
- ProtoOption.match("option foo = \"test value';")
+ ProtoOption.match(None, "option foo = \"test value';")
def test_identifier_option(self):
- identifier_option = ProtoOption.match("option foo = test_identifier;")
- self.assertEqual(identifier_option.node.name, ProtoIdentifier("foo"))
+ identifier_option = ProtoOption.match(None, "option foo = test_identifier;")
+ self.assertEqual(identifier_option.node.name, ProtoIdentifier(None, "foo"))
self.assertEqual(
identifier_option.node.value,
- ProtoConstant(ProtoIdentifier("test_identifier")),
+ ProtoConstant(None, ProtoIdentifier(None, "test_identifier")),
)
self.assertEqual(identifier_option.remaining_source, "")
- identifier_option = ProtoOption.match("option bar = foo.bar.baz;")
- self.assertEqual(identifier_option.node.name, ProtoIdentifier("bar"))
+ identifier_option = ProtoOption.match(None, "option bar = foo.bar.baz;")
+ self.assertEqual(identifier_option.node.name, ProtoIdentifier(None, "bar"))
self.assertEqual(
identifier_option.node.value,
- ProtoConstant(ProtoFullIdentifier("foo.bar.baz")),
+ ProtoConstant(None, ProtoFullIdentifier(None, "foo.bar.baz")),
)
self.assertEqual(identifier_option.remaining_source, "")
def test_int_option(self):
- int_option = ProtoOption.match("option foo = 0;")
- self.assertEqual(int_option.node.name, ProtoIdentifier("foo"))
+ int_option = ProtoOption.match(None, "option foo = 0;")
+ self.assertEqual(int_option.node.name, ProtoIdentifier(None, "foo"))
self.assertEqual(
- int_option.node.value, ProtoConstant(ProtoInt(0, ProtoIntSign.POSITIVE))
+ int_option.node.value,
+ ProtoConstant(None, ProtoInt(None, 0, ProtoIntSign.POSITIVE)),
)
self.assertEqual(int_option.remaining_source, "")
- int_option = ProtoOption.match("option foo = 12345;")
- self.assertEqual(int_option.node.name, ProtoIdentifier("foo"))
+ int_option = ProtoOption.match(None, "option foo = 12345;")
+ self.assertEqual(int_option.node.name, ProtoIdentifier(None, "foo"))
self.assertEqual(
- int_option.node.value, ProtoConstant(ProtoInt(12345, ProtoIntSign.POSITIVE))
+ int_option.node.value,
+ ProtoConstant(None, ProtoInt(None, 12345, ProtoIntSign.POSITIVE)),
)
self.assertEqual(int_option.remaining_source, "")
- int_option = ProtoOption.match("option foo = +42;")
- self.assertEqual(int_option.node.name, ProtoIdentifier("foo"))
+ int_option = ProtoOption.match(None, "option foo = +42;")
+ self.assertEqual(int_option.node.name, ProtoIdentifier(None, "foo"))
self.assertEqual(
- int_option.node.value, ProtoConstant(ProtoInt(42, ProtoIntSign.POSITIVE))
+ int_option.node.value,
+ ProtoConstant(None, ProtoInt(None, 42, ProtoIntSign.POSITIVE)),
)
self.assertEqual(int_option.remaining_source, "")
- int_option = ProtoOption.match("option foo = -12;")
- self.assertEqual(int_option.node.name, ProtoIdentifier("foo"))
+ int_option = ProtoOption.match(None, "option foo = -12;")
+ self.assertEqual(int_option.node.name, ProtoIdentifier(None, "foo"))
self.assertEqual(
- int_option.node.value, ProtoConstant(ProtoInt(12, ProtoIntSign.NEGATIVE))
+ int_option.node.value,
+ ProtoConstant(None, ProtoInt(None, 12, ProtoIntSign.NEGATIVE)),
)
self.assertEqual(int_option.remaining_source, "")
def test_float_option(self):
- float_option = ProtoOption.match("option foo = inf;")
+ float_option = ProtoOption.match(None, "option foo = inf;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float("inf"), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(
+ None, ProtoFloat(None, float("inf"), ProtoFloatSign.POSITIVE)
+ ),
)
- float_option = ProtoOption.match("option foo = nan;")
+ float_option = ProtoOption.match(None, "option foo = nan;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float("nan"), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(
+ None, ProtoFloat(None, float("nan"), ProtoFloatSign.POSITIVE)
+ ),
)
- float_option = ProtoOption.match("option foo = 12.1;")
+ float_option = ProtoOption.match(None, "option foo = 12.1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float(12.1), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(None, ProtoFloat(None, float(12.1), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match("option foo = .1;")
+ float_option = ProtoOption.match(None, "option foo = .1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float(0.1), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(None, ProtoFloat(None, float(0.1), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match("option foo = .1e3;")
+ float_option = ProtoOption.match(None, "option foo = .1e3;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float(100), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(None, ProtoFloat(None, float(100), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match("option foo = +12.1;")
+ float_option = ProtoOption.match(None, "option foo = +12.1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float(12.1), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(None, ProtoFloat(None, float(12.1), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match("option foo = +.1;")
+ float_option = ProtoOption.match(None, "option foo = +.1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float(0.1), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(None, ProtoFloat(None, float(0.1), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match("option foo = +.1e2;")
+ float_option = ProtoOption.match(None, "option foo = +.1e2;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float(10), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(None, ProtoFloat(None, float(10), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match("option foo = +.1e-2;")
+ float_option = ProtoOption.match(None, "option foo = +.1e-2;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float(0.001), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(
+ None, ProtoFloat(None, float(0.001), ProtoFloatSign.POSITIVE)
+ ),
)
- float_option = ProtoOption.match("option foo = -.1e0;")
+ float_option = ProtoOption.match(None, "option foo = -.1e0;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float(0.1), ProtoFloatSign.NEGATIVE)),
+ ProtoConstant(None, ProtoFloat(None, float(0.1), ProtoFloatSign.NEGATIVE)),
)
- float_option = ProtoOption.match("option foo = -12E+1;")
+ float_option = ProtoOption.match(None, "option foo = -12E+1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(ProtoFloat(float(120), ProtoFloatSign.NEGATIVE)),
+ ProtoConstant(None, ProtoFloat(None, float(120), ProtoFloatSign.NEGATIVE)),
)
def test_diff_same_option_returns_empty(self):
po1 = ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
po2 = ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
self.assertEqual(ProtoOption.diff(po1, po2), [])
def test_diff_different_option_name_returns_empty(self):
po1 = ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
po2 = ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
self.assertEqual(ProtoOption.diff(po1, po2), [])
def test_diff_different_option_value_returns_option_diff(self):
po1 = ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
po2 = ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("other value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "other value")),
)
self.assertEqual(
ProtoOption.diff(po1, po2),
[
ProtoOptionValueChanged(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
- ProtoConstant(ProtoStringLiteral("other value")),
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoConstant(None, ProtoStringLiteral(None, "other value")),
)
],
)
@@ -245,16 +265,18 @@ def test_diff_different_option_value_returns_option_diff(self):
def test_diff_option_added(self):
po1 = None
po2 = ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
self.assertEqual(
ProtoOption.diff(po1, po2),
[
ProtoOptionAdded(
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
),
],
@@ -262,8 +284,9 @@ def test_diff_option_added(self):
def test_diff_option_removed(self):
po1 = ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
po2 = None
self.assertEqual(
@@ -271,8 +294,9 @@ def test_diff_option_removed(self):
[
ProtoOptionRemoved(
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
),
],
@@ -286,16 +310,19 @@ def test_diff_sets_empty_returns_empty(self):
def test_diff_sets_no_change(self):
set1 = [
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
self.assertEqual(ProtoOption.diff_sets(set1, set1), [])
@@ -304,16 +331,19 @@ def test_diff_sets_all_removed(self):
set1 = []
set2 = [
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
diff = ProtoOption.diff_sets(set1, set2)
@@ -321,8 +351,9 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
),
diff,
@@ -330,8 +361,9 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
)
),
diff,
@@ -339,8 +371,9 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -350,16 +383,19 @@ def test_diff_sets_all_removed(self):
def test_diff_sets_all_added(self):
set1 = [
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
set2 = []
@@ -368,8 +404,9 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
),
diff,
@@ -377,8 +414,9 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
)
),
diff,
@@ -386,8 +424,9 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -397,30 +436,36 @@ def test_diff_sets_all_added(self):
def test_diff_sets_mutually_exclusive(self):
set1 = [
ProtoOption(
- ProtoIdentifier("some.custom.option.but.not.prior"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option.but.not.prior"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
- ProtoIdentifier("ruby_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "ruby_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
ProtoOption(
- ProtoIdentifier("other.option.but.stil.not.prior"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option.but.stil.not.prior"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
set2 = [
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
@@ -429,8 +474,9 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- ProtoIdentifier("some.custom.option.but.not.prior"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option.but.not.prior"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
),
diff,
@@ -438,8 +484,9 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- ProtoIdentifier("other.option.but.stil.not.prior"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option.but.stil.not.prior"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -448,8 +495,9 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- ProtoIdentifier("ruby_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "ruby_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
)
),
diff,
@@ -458,8 +506,9 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -468,8 +517,9 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
),
diff,
@@ -478,8 +528,9 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
)
),
diff,
@@ -490,30 +541,36 @@ def test_diff_sets_mutually_exclusive(self):
def test_diff_sets_overlap(self):
set1 = [
ProtoOption(
- ProtoIdentifier("some.custom.option.but.not.prior"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option.but.not.prior"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.bat")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.bat")),
),
ProtoOption(
- ProtoIdentifier("other.option.but.stil.not.prior"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option.but.stil.not.prior"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
set2 = [
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
@@ -522,8 +579,9 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- ProtoIdentifier("some.custom.option"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
),
diff,
@@ -532,8 +590,9 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- ProtoIdentifier("other.option"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -541,8 +600,9 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- ProtoIdentifier("some.custom.option.but.not.prior"),
- ProtoConstant(ProtoStringLiteral("some value")),
+ None,
+ ProtoIdentifier(None, "some.custom.option.but.not.prior"),
+ ProtoConstant(None, ProtoStringLiteral(None, "some value")),
)
),
diff,
@@ -550,17 +610,18 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- ProtoIdentifier("other.option.but.stil.not.prior"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
+ None,
+ ProtoIdentifier(None, "other.option.but.stil.not.prior"),
+ ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
)
),
diff,
)
self.assertIn(
ProtoOptionValueChanged(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("foo.bar.bat")),
- ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.bat")),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
diff,
)
diff --git a/test/proto_package_test.py b/test/proto_package_test.py
index b6707ba..20289a9 100644
--- a/test/proto_package_test.py
+++ b/test/proto_package_test.py
@@ -11,90 +11,93 @@
class PackageTest(unittest.TestCase):
def test_correct_package(self):
- self.assertEqual(ProtoPackage.match("package foo;").node.package, "foo")
- self.assertEqual(ProtoPackage.match("package foo.bar;").node.package, "foo.bar")
+ self.assertEqual(ProtoPackage.match(None, "package foo;").node.package, "foo")
self.assertEqual(
- ProtoPackage.match("package foo.bar.baz;").node.package, "foo.bar.baz"
+ ProtoPackage.match(None, "package foo.bar;").node.package, "foo.bar"
+ )
+ self.assertEqual(
+ ProtoPackage.match(None, "package foo.bar.baz;").node.package, "foo.bar.baz"
)
def test_package_serialize(self):
self.assertEqual(
- ProtoPackage.match("package foo;").node.serialize(), "package foo;"
+ ProtoPackage.match(None, "package foo;").node.serialize(), "package foo;"
)
self.assertEqual(
- ProtoPackage.match("package foo.bar;").node.serialize(), "package foo.bar;"
+ ProtoPackage.match(None, "package foo.bar;").node.serialize(),
+ "package foo.bar;",
)
self.assertEqual(
- ProtoPackage.match("package foo.bar.baz;").node.serialize(),
+ ProtoPackage.match(None, "package foo.bar.baz;").node.serialize(),
"package foo.bar.baz;",
)
def test_package_malformed(self):
with self.assertRaises(ValueError):
- ProtoPackage.match("package")
+ ProtoPackage.match(None, "package")
with self.assertRaises(ValueError):
- ProtoPackage.match("package;")
+ ProtoPackage.match(None, "package;")
with self.assertRaises(ValueError):
- ProtoPackage.match("package ")
+ ProtoPackage.match(None, "package ")
with self.assertRaises(ValueError):
- ProtoPackage.match("package ;")
+ ProtoPackage.match(None, "package ;")
with self.assertRaises(ValueError):
- ProtoPackage.match("packagefoo")
+ ProtoPackage.match(None, "packagefoo")
with self.assertRaises(ValueError):
- ProtoPackage.match("package foo.")
+ ProtoPackage.match(None, "package foo.")
with self.assertRaises(ValueError):
- ProtoPackage.match("packagefoo.")
+ ProtoPackage.match(None, "packagefoo.")
with self.assertRaises(ValueError):
- ProtoPackage.match("package foo.;")
+ ProtoPackage.match(None, "package foo.;")
with self.assertRaises(ValueError):
- ProtoPackage.match("package foo.bar")
+ ProtoPackage.match(None, "package foo.bar")
with self.assertRaises(ValueError):
- ProtoPackage.match("packagefoo.bar;")
+ ProtoPackage.match(None, "packagefoo.bar;")
def test_diff_same_package_returns_empty(self):
- pp1 = ProtoPackage("my.awesome.package")
- pp2 = ProtoPackage("my.awesome.package")
+ pp1 = ProtoPackage(None, "my.awesome.package")
+ pp2 = ProtoPackage(None, "my.awesome.package")
self.assertEqual(ProtoPackage.diff(pp1, pp2), [])
def test_diff_different_package_returns_package_diff(self):
- pp1 = ProtoPackage("my.awesome.package")
- pp2 = ProtoPackage("my.other.awesome.package")
+ pp1 = ProtoPackage(None, "my.awesome.package")
+ pp2 = ProtoPackage(None, "my.other.awesome.package")
self.assertEqual(
ProtoPackage.diff(pp1, pp2),
[
ProtoPackageChanged(
- ProtoPackage("my.awesome.package"),
- ProtoPackage("my.other.awesome.package"),
+ ProtoPackage(None, "my.awesome.package"),
+ ProtoPackage(None, "my.other.awesome.package"),
)
],
)
def test_diff_package_added(self):
- pp1 = ProtoPackage("my.new.package")
+ pp1 = ProtoPackage(None, "my.new.package")
pp2 = None
self.assertEqual(
ProtoPackage.diff(pp1, pp2),
[
- ProtoPackageAdded(ProtoPackage("my.new.package")),
+ ProtoPackageAdded(ProtoPackage(None, "my.new.package")),
],
)
def test_diff_package_removed(self):
pp1 = None
- pp2 = ProtoPackage("my.old.package")
+ pp2 = ProtoPackage(None, "my.old.package")
self.assertEqual(
ProtoPackage.diff(pp1, pp2),
[
- ProtoPackageRemoved(ProtoPackage("my.old.package")),
+ ProtoPackageRemoved(ProtoPackage(None, "my.old.package")),
],
)
diff --git a/test/proto_range_test.py b/test/proto_range_test.py
index ce78433..24f90a5 100644
--- a/test/proto_range_test.py
+++ b/test/proto_range_test.py
@@ -5,38 +5,42 @@
class RangeTest(unittest.TestCase):
def test_range_single_int(self):
- self.assertEqual(ProtoRange.match("42").node.serialize(), "42")
- self.assertEqual(ProtoRange.match("-1").node.serialize(), "-1")
+ self.assertEqual(ProtoRange.match(None, "42").node.serialize(), "42")
+ self.assertEqual(ProtoRange.match(None, "-1").node.serialize(), "-1")
def test_range_invalid_non_ints(self):
- self.assertIsNone(ProtoRange.match("42.5"))
- self.assertIsNone(ProtoRange.match("a"))
- self.assertIsNone(ProtoRange.match("-"))
+ self.assertIsNone(ProtoRange.match(None, "42.5"))
+ self.assertIsNone(ProtoRange.match(None, "a"))
+ self.assertIsNone(ProtoRange.match(None, "-"))
def test_range_int_range(self):
- self.assertEqual(ProtoRange.match("1 to 1").node.serialize(), "1 to 1")
- self.assertEqual(ProtoRange.match("1 to 7").node.serialize(), "1 to 7")
- self.assertEqual(ProtoRange.match("-100 to -5").node.serialize(), "-100 to -5")
+ self.assertEqual(ProtoRange.match(None, "1 to 1").node.serialize(), "1 to 1")
+ self.assertEqual(ProtoRange.match(None, "1 to 7").node.serialize(), "1 to 7")
+ self.assertEqual(
+ ProtoRange.match(None, "-100 to -5").node.serialize(), "-100 to -5"
+ )
def test_range_invalid_range(self):
with self.assertRaises(ValueError):
- ProtoRange.match("8 to 2")
+ ProtoRange.match(None, "8 to 2")
with self.assertRaises(ValueError):
- ProtoRange.match("3 to 0")
+ ProtoRange.match(None, "3 to 0")
with self.assertRaises(ValueError):
- ProtoRange.match("1 to -1")
+ ProtoRange.match(None, "1 to -1")
def test_range_invalid_range_non_int(self):
with self.assertRaises(ValueError):
- ProtoRange.match("1 to c")
+ ProtoRange.match(None, "1 to c")
with self.assertRaises(ValueError):
- ProtoRange.match("1 to -bc3")
+ ProtoRange.match(None, "1 to -bc3")
def test_range_max(self):
- self.assertEqual(ProtoRange.match("7 to max").node.serialize(), "7 to max")
+ self.assertEqual(
+ ProtoRange.match(None, "7 to max").node.serialize(), "7 to max"
+ )
if __name__ == "__main__":
diff --git a/test/proto_reserved_test.py b/test/proto_reserved_test.py
index 0232905..f7d1c8b 100644
--- a/test/proto_reserved_test.py
+++ b/test/proto_reserved_test.py
@@ -7,45 +7,47 @@
class ReservedTest(unittest.TestCase):
def test_reserved_single_int(self):
self.assertEqual(
- ProtoReserved.match("reserved 21;").node.serialize(), "reserved 21;"
+ ProtoReserved.match(None, "reserved 21;").node.serialize(), "reserved 21;"
)
self.assertEqual(
- ProtoReserved.match("reserved -1;").node.serialize(), "reserved -1;"
+ ProtoReserved.match(None, "reserved -1;").node.serialize(), "reserved -1;"
)
def test_reserved_multiple_ints(self):
self.assertEqual(
- ProtoReserved.match("reserved 1, 5, 2, 42;").node.serialize(),
+ ProtoReserved.match(None, "reserved 1, 5, 2, 42;").node.serialize(),
"reserved 1, 5, 2, 42;",
)
def test_reserved_range_max(self):
self.assertEqual(
- ProtoReserved.match("reserved 8 to max;").node.serialize(),
+ ProtoReserved.match(None, "reserved 8 to max;").node.serialize(),
"reserved 8 to max;",
)
def test_reserved_single_string_field(self):
self.assertEqual(
- ProtoReserved.match("reserved 'foo';").node.serialize(), "reserved 'foo';"
+ ProtoReserved.match(None, "reserved 'foo';").node.serialize(),
+ "reserved 'foo';",
)
self.assertEqual(
- ProtoReserved.match('reserved "foo";').node.serialize(), 'reserved "foo";'
+ ProtoReserved.match(None, 'reserved "foo";').node.serialize(),
+ 'reserved "foo";',
)
def test_reserved_multiple_string_fields(self):
self.assertEqual(
- ProtoReserved.match("reserved 'foo', 'bar';").node.serialize(),
+ ProtoReserved.match(None, "reserved 'foo', 'bar';").node.serialize(),
"reserved 'foo', 'bar';",
)
self.assertEqual(
- ProtoReserved.match('reserved "foo", "bar", "baz";').node.serialize(),
+ ProtoReserved.match(None, 'reserved "foo", "bar", "baz";').node.serialize(),
'reserved "foo", "bar", "baz";',
)
def test_reserved_cannot_have_ints_and_strings(self):
with self.assertRaises(ValueError):
- ProtoReserved.match("reserved 1, 'foo';")
+ ProtoReserved.match(None, "reserved 1, 'foo';")
if __name__ == "__main__":
diff --git a/test/proto_service_test.py b/test/proto_service_test.py
index f294e02..b99a242 100644
--- a/test/proto_service_test.py
+++ b/test/proto_service_test.py
@@ -20,6 +20,7 @@ class ServiceTest(unittest.TestCase):
def test_service_all_features(self):
test_service_all_features = ProtoService.match(
+ None,
dedent(
"""
service FooService {
@@ -35,47 +36,57 @@ def test_service_all_features(self):
rpc ThreeRPC (ThreeRPCRequest) returns (ThreeRPCResponse) { option java_package = "com.example.foo"; option (foo.bar).baz = false; }
}
""".strip()
- )
+ ),
)
self.assertEqual(
test_service_all_features.node,
ProtoService(
- ProtoIdentifier("FooService"),
+ None,
+ ProtoIdentifier(None, "FooService"),
[
ProtoOption(
- ProtoIdentifier("(foo.bar).baz"),
- ProtoConstant(ProtoStringLiteral("bat")),
+ None,
+ ProtoIdentifier(None, "(foo.bar).baz"),
+ ProtoConstant(None, ProtoStringLiteral(None, "bat")),
),
- ProtoSingleLineComment(" single-line comment!"),
+ ProtoSingleLineComment(None, " single-line comment!"),
ProtoServiceRPC(
- ProtoIdentifier("OneRPC"),
- ProtoEnumOrMessageIdentifier("OneRPCRequest"),
- ProtoEnumOrMessageIdentifier("OneRPCResponse"),
+ None,
+ ProtoIdentifier(None, "OneRPC"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
),
ProtoServiceRPC(
- ProtoIdentifier("TwoRPC"),
- ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
+ None,
+ ProtoIdentifier(None, "TwoRPC"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
False,
True,
),
ProtoMultiLineComment(
- "\n multiple\n line\n comment\n "
+ None,
+ "\n multiple\n line\n comment\n ",
),
ProtoServiceRPC(
- ProtoIdentifier("ThreeRPC"),
- ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
+ None,
+ ProtoIdentifier(None, "ThreeRPC"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
False,
False,
[
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(
+ None, ProtoStringLiteral(None, "com.example.foo")
+ ),
),
ProtoOption(
- ProtoFullIdentifier("(foo.bar).baz"),
- ProtoConstant(ProtoBool(False)),
+ None,
+ ProtoFullIdentifier(None, "(foo.bar).baz"),
+ ProtoConstant(None, ProtoBool(None, False)),
),
],
),
@@ -103,26 +114,31 @@ def test_service_all_features(self):
)
def test_service_empty(self):
- parsed_empty_service = ProtoService.match("""service FooService {}""")
+ parsed_empty_service = ProtoService.match(None, """service FooService {}""")
self.assertIsNotNone(parsed_empty_service)
- self.assertEqual(parsed_empty_service.node.name, ProtoIdentifier("FooService"))
+ self.assertEqual(
+ parsed_empty_service.node.name, ProtoIdentifier(None, "FooService")
+ )
parsed_spaced_service = ProtoService.match(
+ None,
dedent(
"""
service FooService {
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(parsed_spaced_service)
self.assertEqual(
- parsed_spaced_service.node, ProtoService(ProtoIdentifier("FooService"), [])
+ parsed_spaced_service.node,
+ ProtoService(None, ProtoIdentifier(None, "FooService"), []),
)
def test_service_empty_statements(self):
empty_statement_service = ProtoService.match(
+ None,
dedent(
"""
service FooService {
@@ -130,36 +146,39 @@ def test_service_empty_statements(self):
;
}
""".strip()
- )
+ ),
)
self.assertIsNotNone(empty_statement_service)
self.assertEqual(
empty_statement_service.node,
- ProtoService(ProtoIdentifier("FooService"), []),
+ ProtoService(None, ProtoIdentifier(None, "FooService"), []),
)
def test_service_option(self):
service_with_options = ProtoService.match(
+ None,
dedent(
"""
service FooService {
option (foo.bar).baz = "bat";
}
""".strip()
- )
+ ),
)
self.assertEqual(
service_with_options.node.nodes,
[
ProtoOption(
- ProtoIdentifier("(foo.bar).baz"),
- ProtoConstant(ProtoStringLiteral("bat")),
+ None,
+ ProtoIdentifier(None, "(foo.bar).baz"),
+ ProtoConstant(None, ProtoStringLiteral(None, "bat")),
)
],
)
def test_service_rpc_basic(self):
service_with_options = ProtoService.match(
+ None,
dedent(
"""
service FooService {
@@ -168,31 +187,35 @@ def test_service_rpc_basic(self):
rpc ThreeRPC (ThreeRPCRequest) returns (ThreeRPCResponse);
}
""".strip()
- )
+ ),
)
self.assertEqual(
service_with_options.node.nodes,
[
ProtoServiceRPC(
- ProtoIdentifier("OneRPC"),
- ProtoEnumOrMessageIdentifier("OneRPCRequest"),
- ProtoEnumOrMessageIdentifier("OneRPCResponse"),
+ None,
+ ProtoIdentifier(None, "OneRPC"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
),
ProtoServiceRPC(
- ProtoIdentifier("TwoRPC"),
- ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
+ None,
+ ProtoIdentifier(None, "TwoRPC"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
),
ProtoServiceRPC(
- ProtoIdentifier("ThreeRPC"),
- ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
+ None,
+ ProtoIdentifier(None, "ThreeRPC"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
),
],
)
def test_service_rpc_stream(self):
service_with_options = ProtoService.match(
+ None,
dedent(
"""
service FooService {
@@ -200,22 +223,24 @@ def test_service_rpc_stream(self):
rpc TwoRPC (TwoRPCRequest) returns (stream TwoRPCResponse);
}
""".strip()
- )
+ ),
)
self.assertEqual(
service_with_options.node.nodes,
[
ProtoServiceRPC(
- ProtoIdentifier("OneRPC"),
- ProtoEnumOrMessageIdentifier("OneRPCRequest"),
- ProtoEnumOrMessageIdentifier("OneRPCResponse"),
+ None,
+ ProtoIdentifier(None, "OneRPC"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
True,
False,
),
ProtoServiceRPC(
- ProtoIdentifier("TwoRPC"),
- ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
+ None,
+ ProtoIdentifier(None, "TwoRPC"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
False,
True,
),
@@ -224,6 +249,7 @@ def test_service_rpc_stream(self):
def test_service_rpc_options(self):
service_with_options = ProtoService.match(
+ None,
dedent(
"""
service FooService {
@@ -231,30 +257,36 @@ def test_service_rpc_options(self):
rpc TwoRPC (TwoRPCRequest) returns (TwoRPCResponse) { option java_package = "com.example.foo"; option (foo.bar).baz = false; }
}
""".strip()
- )
+ ),
)
self.assertEqual(
service_with_options.node.nodes,
[
ProtoServiceRPC(
- ProtoIdentifier("OneRPC"),
- ProtoEnumOrMessageIdentifier("OneRPCRequest"),
- ProtoEnumOrMessageIdentifier("OneRPCResponse"),
+ None,
+ ProtoIdentifier(None, "OneRPC"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
),
ProtoServiceRPC(
- ProtoIdentifier("TwoRPC"),
- ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
+ None,
+ ProtoIdentifier(None, "TwoRPC"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
False,
False,
[
ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(
+ None, ProtoStringLiteral(None, "com.example.foo")
+ ),
),
ProtoOption(
- ProtoFullIdentifier("(foo.bar).baz"),
- ProtoConstant(ProtoBool(False)),
+ None,
+ ProtoFullIdentifier(None, "(foo.bar).baz"),
+ ProtoConstant(None, ProtoBool(None, False)),
),
],
),
@@ -263,6 +295,7 @@ def test_service_rpc_options(self):
def test_service_parses_comments(self):
service_with_comments = ProtoService.match(
+ None,
dedent(
"""
service FooService {
@@ -277,35 +310,40 @@ def test_service_parses_comments(self):
rpc ThreeRPC (ThreeRPCRequest) returns (ThreeRPCResponse);
}
""".strip()
- )
+ ),
)
self.assertEqual(
service_with_comments.node.nodes,
[
ProtoServiceRPC(
- ProtoIdentifier("OneRPC"),
- ProtoEnumOrMessageIdentifier("OneRPCRequest"),
- ProtoEnumOrMessageIdentifier("OneRPCResponse"),
+ None,
+ ProtoIdentifier(None, "OneRPC"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
),
- ProtoSingleLineComment(" single-line comment!"),
+ ProtoSingleLineComment(None, " single-line comment!"),
ProtoServiceRPC(
- ProtoIdentifier("TwoRPC"),
- ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
+ None,
+ ProtoIdentifier(None, "TwoRPC"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
),
ProtoMultiLineComment(
- "\n multiple\n line\n comment\n "
+ None,
+ "\n multiple\n line\n comment\n ",
),
ProtoServiceRPC(
- ProtoIdentifier("ThreeRPC"),
- ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
+ None,
+ ProtoIdentifier(None, "ThreeRPC"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
),
],
)
def test_service_normalize_removes_comments(self):
normalized_service = ProtoService.match(
+ None,
dedent(
"""
service FooService {
@@ -320,25 +358,28 @@ def test_service_normalize_removes_comments(self):
rpc ThreeRPC (ThreeRPCRequest) returns (ThreeRPCResponse);
}
""".strip()
- )
+ ),
).node.normalize()
self.assertEqual(
normalized_service.nodes,
[
ProtoServiceRPC(
- ProtoIdentifier("OneRPC"),
- ProtoEnumOrMessageIdentifier("OneRPCRequest"),
- ProtoEnumOrMessageIdentifier("OneRPCResponse"),
+ None,
+ ProtoIdentifier(None, "OneRPC"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
),
ProtoServiceRPC(
- ProtoIdentifier("ThreeRPC"),
- ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
+ None,
+ ProtoIdentifier(None, "ThreeRPC"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
),
ProtoServiceRPC(
- ProtoIdentifier("TwoRPC"),
- ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
+ None,
+ ProtoIdentifier(None, "TwoRPC"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
),
],
)
diff --git a/test/proto_string_literal_test.py b/test/proto_string_literal_test.py
index 73ad4dc..b3bb303 100644
--- a/test/proto_string_literal_test.py
+++ b/test/proto_string_literal_test.py
@@ -5,33 +5,33 @@
class StringLiteralTest(unittest.TestCase):
def test_correct_syntax(self):
- parsed_single_quote = ProtoStringLiteral.match("""'foo'""")
+ parsed_single_quote = ProtoStringLiteral.match(None, """'foo'""")
self.assertEqual(parsed_single_quote.node.value, "foo")
self.assertEqual(parsed_single_quote.remaining_source, "")
self.assertEqual(parsed_single_quote.node.serialize(), "'foo'")
- parsed_double_quote = ProtoStringLiteral.match("""\"foo\"""")
+ parsed_double_quote = ProtoStringLiteral.match(None, """\"foo\"""")
self.assertEqual(parsed_double_quote.node.value, "foo")
self.assertEqual(parsed_double_quote.remaining_source, "")
self.assertEqual(parsed_double_quote.node.serialize(), '"foo"')
def test_remaining_source(self):
- parsed_single_quote = ProtoStringLiteral.match("""'foo'\nbar baz""")
+ parsed_single_quote = ProtoStringLiteral.match(None, """'foo'\nbar baz""")
self.assertEqual(parsed_single_quote.remaining_source, "bar baz")
- parsed_double_quote = ProtoStringLiteral.match("""\"foo\"\"foobar\"""")
+ parsed_double_quote = ProtoStringLiteral.match(None, """\"foo\"\"foobar\"""")
self.assertEqual(parsed_double_quote.remaining_source, '"foobar"')
def test_missing_quote(self):
- self.assertIsNone(ProtoStringLiteral.match("""'foo"""))
- self.assertIsNone(ProtoStringLiteral.match("""foo'"""))
- self.assertIsNone(ProtoStringLiteral.match("""\"foo"""))
- self.assertIsNone(ProtoStringLiteral.match("""foo\""""))
- self.assertIsNone(ProtoStringLiteral.match("""'foo\""""))
- self.assertIsNone(ProtoStringLiteral.match("""\"foo'"""))
+ self.assertIsNone(ProtoStringLiteral.match(None, """'foo"""))
+ self.assertIsNone(ProtoStringLiteral.match(None, """foo'"""))
+ self.assertIsNone(ProtoStringLiteral.match(None, """\"foo"""))
+ self.assertIsNone(ProtoStringLiteral.match(None, """foo\""""))
+ self.assertIsNone(ProtoStringLiteral.match(None, """'foo\""""))
+ self.assertIsNone(ProtoStringLiteral.match(None, """\"foo'"""))
def test_escaped_quote(self):
- self.assertIsNone(ProtoStringLiteral.match("""'foo\\'"""))
- self.assertIsNone(ProtoStringLiteral.match("""\"foo\\\""""))
- parsed_escaped_quote = ProtoStringLiteral.match("""\"foo\\\"barbaz\"""")
+ self.assertIsNone(ProtoStringLiteral.match(None, """'foo\\'"""))
+ self.assertIsNone(ProtoStringLiteral.match(None, """\"foo\\\""""))
+ parsed_escaped_quote = ProtoStringLiteral.match(None, """\"foo\\\"barbaz\"""")
self.assertEqual(parsed_escaped_quote.node.value, 'foo\\"barbaz')
self.assertEqual(parsed_escaped_quote.remaining_source, "")
self.assertEqual(parsed_escaped_quote.node.serialize(), '"foo\\"barbaz"')
diff --git a/test/proto_syntax_test.py b/test/proto_syntax_test.py
index 6abfda1..d0e4a3f 100644
--- a/test/proto_syntax_test.py
+++ b/test/proto_syntax_test.py
@@ -7,88 +7,88 @@
class SyntaxTest(unittest.TestCase):
def test_correct_syntax(self):
self.assertEqual(
- ProtoSyntax.match("syntax = 'proto3';").node.syntax.value, "proto3"
+ ProtoSyntax.match(None, "syntax = 'proto3';").node.syntax.value, "proto3"
)
self.assertEqual(
- ProtoSyntax.match('syntax = "proto3";').node.syntax.value, "proto3"
+ ProtoSyntax.match(None, 'syntax = "proto3";').node.syntax.value, "proto3"
)
self.assertEqual(
- ProtoSyntax.match("syntax = 'proto2';").node.syntax.value, "proto2"
+ ProtoSyntax.match(None, "syntax = 'proto2';").node.syntax.value, "proto2"
)
self.assertEqual(
- ProtoSyntax.match('syntax = "proto2";').node.syntax.value, "proto2"
+ ProtoSyntax.match(None, 'syntax = "proto2";').node.syntax.value, "proto2"
)
def test_serialize(self):
self.assertEqual(
- ProtoSyntax.match("syntax = 'proto3';").node.serialize(),
+ ProtoSyntax.match(None, "syntax = 'proto3';").node.serialize(),
"syntax = 'proto3';",
)
self.assertEqual(
- ProtoSyntax.match('syntax = "proto3";').node.serialize(),
+ ProtoSyntax.match(None, 'syntax = "proto3";').node.serialize(),
'syntax = "proto3";',
)
self.assertEqual(
- ProtoSyntax.match("syntax = 'proto2';").node.serialize(),
+ ProtoSyntax.match(None, "syntax = 'proto2';").node.serialize(),
"syntax = 'proto2';",
)
self.assertEqual(
- ProtoSyntax.match('syntax = "proto2";').node.serialize(),
+ ProtoSyntax.match(None, 'syntax = "proto2";').node.serialize(),
'syntax = "proto2";',
)
def test_syntax_not_present(self):
- self.assertIsNone(ProtoSyntax.match(""))
- self.assertIsNone(ProtoSyntax.match('import "foo.proto";'))
+ self.assertIsNone(ProtoSyntax.match(None, ""))
+ self.assertIsNone(ProtoSyntax.match(None, 'import "foo.proto";'))
def test_syntax_malformed(self):
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = 'proto3'")
+ ProtoSyntax.match(None, "syntax = 'proto3'")
with self.assertRaises(ValueError):
- ProtoSyntax.match('syntax = "proto3"')
+ ProtoSyntax.match(None, 'syntax = "proto3"')
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = 'proto2'")
+ ProtoSyntax.match(None, "syntax = 'proto2'")
with self.assertRaises(ValueError):
- ProtoSyntax.match('syntax = "proto2"')
+ ProtoSyntax.match(None, 'syntax = "proto2"')
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = proto3")
+ ProtoSyntax.match(None, "syntax = proto3")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = proto3;")
+ ProtoSyntax.match(None, "syntax = proto3;")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = 'proto3")
+ ProtoSyntax.match(None, "syntax = 'proto3")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = 'proto3;")
+ ProtoSyntax.match(None, "syntax = 'proto3;")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = proto3'")
+ ProtoSyntax.match(None, "syntax = proto3'")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = proto3';")
+ ProtoSyntax.match(None, "syntax = proto3';")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = 'proton';")
+ ProtoSyntax.match(None, "syntax = 'proton';")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = 'proton'")
+ ProtoSyntax.match(None, "syntax = 'proton'")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = 'proton")
+ ProtoSyntax.match(None, "syntax = 'proton")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = proton';")
+ ProtoSyntax.match(None, "syntax = proton';")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = proton'")
+ ProtoSyntax.match(None, "syntax = proton'")
with self.assertRaises(ValueError):
- ProtoSyntax.match("syntax = proton")
+ ProtoSyntax.match(None, "syntax = proton")
def test_diff_empty_same_syntax_returns_empty(self):
- pf1 = ProtoSyntax(ProtoStringLiteral("proto3"))
- pf2 = ProtoSyntax(ProtoStringLiteral("proto3"))
+ pf1 = ProtoSyntax(None, ProtoStringLiteral(None, "proto3"))
+ pf2 = ProtoSyntax(None, ProtoStringLiteral(None, "proto3"))
self.assertEqual(ProtoSyntax.diff(pf1, pf2), [])
def test_diff_empty_different_syntax_returns_syntax_diff(self):
- pf1 = ProtoSyntax(ProtoStringLiteral("proto3"))
- pf2 = ProtoSyntax(ProtoStringLiteral("proto2"))
+ pf1 = ProtoSyntax(None, ProtoStringLiteral(None, "proto3"))
+ pf2 = ProtoSyntax(None, ProtoStringLiteral(None, "proto2"))
self.assertEqual(
ProtoSyntax.diff(pf1, pf2),
[
ProtoSyntaxChanged(
- ProtoSyntax(ProtoStringLiteral("proto3")),
- ProtoSyntax(ProtoStringLiteral("proto2")),
+ ProtoSyntax(None, ProtoStringLiteral(None, "proto3")),
+ ProtoSyntax(None, ProtoStringLiteral(None, "proto2")),
)
],
)
From 1d4c1e7e1bcd06ada6b97a255d554c7edb1e2f67 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sat, 18 Feb 2023 23:08:20 -0500
Subject: [PATCH 12/35] Pull proto_map, proto_oneof out of proto_message (#69)
---
src/BUILD.bazel | 29 +++
src/proto_map.py | 283 ++++++++++++++++++++++++
src/proto_message.py | 438 +------------------------------------
src/proto_oneof.py | 159 ++++++++++++++
test/BUILD.bazel | 25 ++-
test/parser_test.py | 9 +-
test/proto_extend_test.py | 2 +-
test/proto_map_test.py | 100 +++++++++
test/proto_message_test.py | 4 +-
9 files changed, 605 insertions(+), 444 deletions(-)
create mode 100644 src/proto_map.py
create mode 100644 src/proto_oneof.py
create mode 100644 test/proto_map_test.py
diff --git a/src/BUILD.bazel b/src/BUILD.bazel
index 892c9a3..899a7d5 100644
--- a/src/BUILD.bazel
+++ b/src/BUILD.bazel
@@ -173,12 +173,41 @@ py_library(
":proto_extend",
":proto_extensions",
":proto_identifier",
+ ":proto_map",
+ ":proto_message_field",
":proto_node",
+ ":proto_oneof",
":proto_option",
":proto_reserved",
],
)
+py_library(
+ name = "proto_oneof",
+ srcs = ["proto_oneof.py"],
+ visibility = ["//visibility:public"],
+ deps = [
+ ":proto_comment",
+ ":proto_identifier",
+ ":proto_map",
+ ":proto_message_field",
+ ":proto_node",
+ ":proto_option",
+ ],
+)
+
+py_library(
+ name = "proto_map",
+ srcs = ["proto_map.py"],
+ visibility = ["//visibility:public"],
+ deps = [
+ ":proto_identifier",
+ ":proto_int",
+ ":proto_message_field",
+ ":proto_node",
+ ],
+)
+
py_library(
name = "proto_enum",
srcs = ["proto_enum.py"],
diff --git a/src/proto_map.py b/src/proto_map.py
new file mode 100644
index 0000000..9d73594
--- /dev/null
+++ b/src/proto_map.py
@@ -0,0 +1,283 @@
+from enum import Enum
+from typing import Optional, Sequence
+
+from src.proto_identifier import ProtoEnumOrMessageIdentifier, ProtoIdentifier
+from src.proto_int import ProtoInt
+from src.proto_message_field import ProtoMessageFieldOption, ProtoMessageFieldTypesEnum
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
+
+
+class ProtoMapKeyTypesEnum(Enum):
+ INT32 = "int32"
+ INT64 = "int64"
+ UINT32 = "uint32"
+ UINT64 = "uint64"
+ SINT32 = "sint32"
+ SINT64 = "sint64"
+ FIXED32 = "fixed32"
+ FIXED64 = "fixed64"
+ SFIXED32 = "sfixed32"
+ SFIXED64 = "sfixed64"
+ BOOL = "bool"
+ STRING = "string"
+
+
+ProtoMapValueTypesEnum = ProtoMessageFieldTypesEnum
+
+
+class ProtoMap(ProtoNode):
+ def __init__(
+ self,
+ parent: Optional[ProtoNode],
+ key_type: ProtoMapKeyTypesEnum,
+ value_type: ProtoMapValueTypesEnum,
+ name: ProtoIdentifier,
+ number: ProtoInt,
+ enum_or_message_type_name: Optional[ProtoEnumOrMessageIdentifier] = None,
+ options: Optional[list[ProtoMessageFieldOption]] = None,
+ ):
+ super().__init__(parent)
+ self.key_type = key_type
+ self.value_type = value_type
+ self.name = name
+ self.name.parent = self
+ self.number = number
+ self.number.parent = self
+ self.enum_or_message_type_name = enum_or_message_type_name
+ if self.enum_or_message_type_name is not None:
+ self.enum_or_message_type_name.parent = self
+
+ if options is None:
+ options = []
+ self.options = options
+ for option in self.options:
+ option.parent = self
+
+ def __eq__(self, other) -> bool:
+ return (
+ self.key_type == other.key_type
+ and self.value_type == other.value_type
+ and self.name == other.name
+ and self.number == other.number
+ and self.enum_or_message_type_name == other.enum_or_message_type_name
+ and self.options == other.options
+ )
+
+ def __str__(self) -> str:
+ return f"<{self.__class__.__name__} key_type={self.key_type} value_type={self.value_type} name={self.name} number={self.number} enum_or_message_type_name={self.enum_or_message_type_name} options={self.options}>"
+
+ def __repr__(self) -> str:
+ return str(self)
+
+ def normalize(self) -> "ProtoMap":
+ return ProtoMap(
+ parent=self.parent,
+ key_type=self.key_type,
+ value_type=self.value_type,
+ name=self.name,
+ number=self.number,
+ enum_or_message_type_name=self.enum_or_message_type_name,
+ options=sorted(self.options, key=lambda o: str(o.normalize())),
+ )
+
+ @classmethod
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoNode"]:
+ if proto_source.startswith("map "):
+ proto_source = proto_source[4:].strip()
+ elif proto_source.startswith("map<"):
+ proto_source = proto_source[3:].strip()
+ else:
+ return None
+
+ # Try to match the map key type.
+ proto_source = proto_source[1:].strip()
+ key_type = None
+ for potential_key_type in ProtoMapKeyTypesEnum:
+ if proto_source.startswith(potential_key_type.value):
+ key_type = potential_key_type
+ proto_source = proto_source[len(potential_key_type.value) :].strip()
+ break
+ if key_type is None:
+ return None
+
+ if not proto_source.startswith(","):
+ return None
+ proto_source = proto_source[1:].strip()
+
+ # Next, try to match the map value type.
+ value_type: Optional[ProtoMapValueTypesEnum] = None
+ for potential_value_type in ProtoMapValueTypesEnum:
+ if potential_value_type == ProtoMapValueTypesEnum.ENUM_OR_MESSAGE:
+ # This is special-cased below.
+ break
+ if proto_source.startswith(potential_value_type.value):
+ value_type = potential_value_type
+ proto_source = proto_source[len(potential_value_type.value) :].strip()
+
+ # If this is an enum or message type, try to match a name.
+ enum_or_message_type_name = None
+ if value_type is None:
+ # See if this is an enum or message type.
+ match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
+ if match is None:
+ return None
+ value_type = ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE
+ enum_or_message_type_name = match.node
+ proto_source = match.remaining_source.strip()
+
+ if not proto_source.startswith(">"):
+ return None
+ proto_source = proto_source[1:].strip()
+
+ # Try to match the map field's name.
+ identifier_match = ProtoIdentifier.match(None, proto_source)
+ if identifier_match is None:
+ return None
+ name = identifier_match.node
+ proto_source = identifier_match.remaining_source.strip()
+
+ if not proto_source.startswith("="):
+ return None
+ proto_source = proto_source[1:].strip()
+
+ # Try to match the map field number.
+ int_match = ProtoInt.match(None, proto_source)
+ if int_match is None:
+ return None
+ number = int_match.node
+ proto_source = int_match.remaining_source.strip()
+
+ # Try to match map field options, if any.
+ options = []
+ if proto_source.startswith("["):
+ proto_source = proto_source[1:].strip()
+ end_bracket = proto_source.find("]")
+ if end_bracket == -1:
+ raise ValueError(
+ f"Proto has invalid map field option syntax, cannot find ]: {proto_source}"
+ )
+ for option_part in proto_source[:end_bracket].strip().split(","):
+ message_field_option_match = ProtoMessageFieldOption.match(
+ None, option_part.strip()
+ )
+ if message_field_option_match is None:
+ raise ValueError(
+ f"Proto has invalid map field option syntax: {proto_source}"
+ )
+ options.append(message_field_option_match.node)
+ proto_source = proto_source[end_bracket + 1 :].strip()
+
+ if not proto_source.startswith(";"):
+ raise ValueError(
+ f"Proto has invalid map field syntax, missing ending ;:{proto_source}"
+ )
+
+ return ParsedProtoNode(
+ ProtoMap(
+ parent,
+ key_type,
+ value_type,
+ name,
+ number,
+ enum_or_message_type_name,
+ options,
+ ),
+ proto_source[1:].strip(),
+ )
+
+ def serialize(self) -> str:
+ serialized_parts = [
+ f"map",
+ f"<{self.key_type.value},",
+ ]
+
+ if self.value_type == ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE:
+ if self.enum_or_message_type_name is None:
+ raise ValueError(
+ f"Enum or message type name was not set for: {str(self)}"
+ )
+ serialized_parts.append(f"{self.enum_or_message_type_name.serialize()}>")
+ else:
+ serialized_parts.append(f"{self.value_type.value}>")
+
+ serialized_parts = serialized_parts + [
+ self.name.serialize(),
+ "=",
+ self.number.serialize(),
+ ]
+
+ if self.options:
+ serialized_parts.append("[")
+ serialized_parts.append(
+ ", ".join(option.serialize() for option in self.options)
+ )
+ serialized_parts.append("]")
+
+ return " ".join(serialized_parts) + ";"
+
+ @staticmethod
+ def diff(
+ parent: Optional[ProtoNode], left: "ProtoMap", right: "ProtoMap"
+ ) -> list["ProtoNodeDiff"]:
+ if left is None and right is not None:
+ return [ProtoMapAdded(parent, right)]
+ elif left is not None and right is None:
+ return [ProtoMapRemoved(parent, left)]
+ elif left is None and right is None:
+ return []
+ elif left.name != right.name:
+ return []
+ elif left == right:
+ return []
+ diffs: list["ProtoNodeDiff"] = []
+ return diffs
+
+ @staticmethod
+ def diff_sets(
+ parent: Optional[ProtoNode], left: list["ProtoMap"], right: list["ProtoMap"]
+ ) -> Sequence["ProtoNodeDiff"]:
+ diffs: list[ProtoNodeDiff] = []
+ left_names = set(o.name.identifier for o in left)
+ right_names = set(o.name.identifier for o in right)
+ for name in left_names - right_names:
+ diffs.append(
+ ProtoMapAdded(
+ parent, next(i for i in left if i.name.identifier == name)
+ )
+ )
+ for name in right_names - left_names:
+ diffs.append(
+ ProtoMapRemoved(
+ parent, next(i for i in right if i.name.identifier == name)
+ )
+ )
+ for name in left_names & right_names:
+ left_enum = next(i for i in left if i.name.identifier == name)
+ right_enum = next(i for i in right if i.name.identifier == name)
+ diffs.extend(ProtoMap.diff(parent, left_enum, right_enum))
+
+ return diffs
+
+
+class ProtoMapDiff(ProtoNodeDiff):
+ def __init__(self, parent: Optional[ProtoNode], map: ProtoMap):
+ self.parent = parent
+ self.map = map
+
+ def __eq__(self, other: object) -> bool:
+ return isinstance(other, ProtoMapDiff) and self.map == other.map
+
+ def __str__(self) -> str:
+ return f"<{self.__class__.__name__} parent={self.parent} map={self.map}>"
+
+
+class ProtoMapAdded(ProtoMapDiff):
+ def __eq__(self, other: object) -> bool:
+ return super().__eq__(other) and isinstance(other, ProtoMapAdded)
+
+
+class ProtoMapRemoved(ProtoMapDiff):
+ def __eq__(self, other: object) -> bool:
+ return super().__eq__(other) and isinstance(other, ProtoMapRemoved)
diff --git a/src/proto_message.py b/src/proto_message.py
index bf82578..8c084c9 100644
--- a/src/proto_message.py
+++ b/src/proto_message.py
@@ -1,9 +1,6 @@
-from enum import Enum
from typing import Optional, Sequence
from src.proto_comment import (
- ParsedProtoMultiLineCommentNode,
- ParsedProtoSingleLineCommentNode,
ProtoComment,
ProtoMultiLineComment,
ProtoSingleLineComment,
@@ -11,439 +8,14 @@
from src.proto_enum import ProtoEnum
from src.proto_extend import ProtoExtend
from src.proto_extensions import ProtoExtensions
-from src.proto_identifier import ProtoEnumOrMessageIdentifier, ProtoIdentifier
-from src.proto_int import ProtoInt
-from src.proto_message_field import (
- ParsedProtoMessageFieldNode,
- ProtoMessageField,
- ProtoMessageFieldOption,
- ProtoMessageFieldTypesEnum,
-)
+from src.proto_identifier import ProtoIdentifier
+from src.proto_map import ProtoMap
+from src.proto_message_field import ProtoMessageField
from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
-from src.proto_option import ParsedProtoOptionNode, ProtoOption
+from src.proto_oneof import ProtoOneOf
+from src.proto_option import ProtoOption
from src.proto_reserved import ProtoReserved
-ProtoOneOfNodeTypes = (
- ProtoOption | ProtoMessageField | ProtoSingleLineComment | ProtoMultiLineComment
-)
-ProtoParsedOneOfNodeTypes = (
- ParsedProtoOptionNode
- | ParsedProtoMessageFieldNode
- | ParsedProtoSingleLineCommentNode
- | ParsedProtoMultiLineCommentNode
-)
-
-
-class ParsedProtoOneOfNode(ParsedProtoNode):
- node: "ProtoOneOf"
- remaining_source: str
-
-
-class ProtoOneOf(ProtoNode):
- def __init__(
- self,
- parent: Optional[ProtoNode],
- name: ProtoIdentifier,
- nodes: Sequence[ProtoOneOfNodeTypes],
- ):
- super().__init__(parent)
- self.name = name
- self.name.parent = self
- self.nodes = nodes
- for node in self.nodes:
- node.parent = self
-
- def __eq__(self, other) -> bool:
- return self.name == other.name and self.nodes == other.nodes
-
- def __str__(self) -> str:
- return f"<{self.__class__.__name__} name={self.name}, nodes={self.nodes}>"
-
- def __repr__(self) -> str:
- return str(self)
-
- def normalize(self) -> "ProtoOneOf":
- non_comment_nodes = filter(
- lambda n: not isinstance(n, ProtoComment), self.nodes
- )
- options = []
- fields = []
- for node in non_comment_nodes:
- if isinstance(node, ProtoOption):
- options.append(node.normalize())
- elif (
- isinstance(node, ProtoMessageField)
- or isinstance(node, ProtoOneOf)
- or isinstance(node, ProtoMap)
- ):
- fields.append(node.normalize())
- else:
- raise ValueError(
- f"Can't sort message {self} node for normalizing: {node}"
- )
-
- sorted_nodes_for_normalizing = sorted(
- options, key=lambda o: str(o.normalize())
- ) + sorted(fields, key=lambda f: int(f.number))
-
- return ProtoOneOf(
- parent=self.parent,
- name=self.name,
- nodes=sorted_nodes_for_normalizing,
- )
-
- @staticmethod
- def parse_partial_content(partial_oneof_content: str) -> ProtoParsedOneOfNodeTypes:
- supported_types: list[type[ProtoOneOfNodeTypes]] = [
- ProtoMessageField,
- ProtoOption,
- ProtoSingleLineComment,
- ProtoMultiLineComment,
- ]
- for node_type in supported_types:
- try:
- match_result = node_type.match(None, partial_oneof_content)
- except (ValueError, IndexError, TypeError):
- raise ValueError(
- f"Could not parse partial oneof content:\n{partial_oneof_content}"
- )
- if match_result is not None:
- return match_result
- raise ValueError(
- f"Could not parse partial oneof content:\n{partial_oneof_content}"
- )
-
- @classmethod
- def match(
- cls, parent: Optional[ProtoNode], proto_source: str
- ) -> Optional["ParsedProtoOneOfNode"]:
- if not proto_source.startswith("oneof "):
- return None
-
- proto_source = proto_source[6:].strip()
-
- match = ProtoIdentifier.match(None, proto_source)
- if match is None:
- raise ValueError(
- f"Proto has invalid syntax, expecting identifier for oneof: {proto_source}"
- )
-
- oneof_name = match.node
- proto_source = match.remaining_source.strip()
-
- if not proto_source.startswith("{"):
- raise ValueError(
- f"Proto has invalid syntax, expecting opening curly brace: {proto_source}"
- )
-
- proto_source = proto_source[1:].strip()
- parsed_tree = []
- while proto_source:
- # Remove empty statements.
- if proto_source.startswith(";"):
- proto_source = proto_source[1:].strip()
- continue
-
- if proto_source.startswith("}"):
- proto_source = proto_source[1:].strip()
- break
-
- match_result = ProtoOneOf.parse_partial_content(proto_source)
- parsed_tree.append(match_result.node)
- proto_source = match_result.remaining_source.strip()
-
- return ParsedProtoOneOfNode(
- ProtoOneOf(parent, oneof_name, nodes=parsed_tree), proto_source
- )
-
- @property
- def options(self) -> list[ProtoOption]:
- return [node for node in self.nodes if isinstance(node, ProtoOption)]
-
- def serialize(self) -> str:
- serialize_parts = (
- [f"oneof {self.name.serialize()} {{"]
- + [n.serialize() for n in self.nodes]
- + ["}"]
- )
- return "\n".join(serialize_parts)
-
-
-class ProtoMapKeyTypesEnum(Enum):
- INT32 = "int32"
- INT64 = "int64"
- UINT32 = "uint32"
- UINT64 = "uint64"
- SINT32 = "sint32"
- SINT64 = "sint64"
- FIXED32 = "fixed32"
- FIXED64 = "fixed64"
- SFIXED32 = "sfixed32"
- SFIXED64 = "sfixed64"
- BOOL = "bool"
- STRING = "string"
-
-
-ProtoMapValueTypesEnum = ProtoMessageFieldTypesEnum
-
-
-class ProtoMap(ProtoNode):
- def __init__(
- self,
- parent: Optional[ProtoNode],
- key_type: ProtoMapKeyTypesEnum,
- value_type: ProtoMapValueTypesEnum,
- name: ProtoIdentifier,
- number: ProtoInt,
- enum_or_message_type_name: Optional[ProtoEnumOrMessageIdentifier] = None,
- options: Optional[list[ProtoMessageFieldOption]] = None,
- ):
- super().__init__(parent)
- self.key_type = key_type
- self.value_type = value_type
- self.name = name
- self.name.parent = self
- self.number = number
- self.number.parent = self
- self.enum_or_message_type_name = enum_or_message_type_name
- if self.enum_or_message_type_name is not None:
- self.enum_or_message_type_name.parent = self
-
- if options is None:
- options = []
- self.options = options
- for option in self.options:
- option.parent = self
-
- def __eq__(self, other) -> bool:
- return (
- self.key_type == other.key_type
- and self.value_type == other.value_type
- and self.name == other.name
- and self.number == other.number
- and self.enum_or_message_type_name == other.enum_or_message_type_name
- and self.options == other.options
- )
-
- def __str__(self) -> str:
- return f"<{self.__class__.__name__} key_type={self.key_type} value_type={self.value_type} name={self.name} number={self.number} enum_or_message_type_name={self.enum_or_message_type_name} options={self.options}>"
-
- def __repr__(self) -> str:
- return str(self)
-
- def normalize(self) -> "ProtoMap":
- return ProtoMap(
- parent=self.parent,
- key_type=self.key_type,
- value_type=self.value_type,
- name=self.name,
- number=self.number,
- enum_or_message_type_name=self.enum_or_message_type_name,
- options=sorted(self.options, key=lambda o: str(o.normalize())),
- )
-
- @classmethod
- def match(
- cls, parent: Optional[ProtoNode], proto_source: str
- ) -> Optional["ParsedProtoNode"]:
- if proto_source.startswith("map "):
- proto_source = proto_source[4:].strip()
- elif proto_source.startswith("map<"):
- proto_source = proto_source[3:].strip()
- else:
- return None
-
- # Try to match the map key type.
- proto_source = proto_source[1:].strip()
- key_type = None
- for potential_key_type in ProtoMapKeyTypesEnum:
- if proto_source.startswith(potential_key_type.value):
- key_type = potential_key_type
- proto_source = proto_source[len(potential_key_type.value) :].strip()
- break
- if key_type is None:
- return None
-
- if not proto_source.startswith(","):
- return None
- proto_source = proto_source[1:].strip()
-
- # Next, try to match the map value type.
- value_type: Optional[ProtoMapValueTypesEnum] = None
- for potential_value_type in ProtoMapValueTypesEnum:
- if potential_value_type == ProtoMapValueTypesEnum.ENUM_OR_MESSAGE:
- # This is special-cased below.
- break
- if proto_source.startswith(potential_value_type.value):
- value_type = potential_value_type
- proto_source = proto_source[len(potential_value_type.value) :].strip()
-
- # If this is an enum or message type, try to match a name.
- enum_or_message_type_name = None
- if value_type is None:
- # See if this is an enum or message type.
- match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
- if match is None:
- return None
- value_type = ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE
- enum_or_message_type_name = match.node
- proto_source = match.remaining_source.strip()
-
- if not proto_source.startswith(">"):
- return None
- proto_source = proto_source[1:].strip()
-
- # Try to match the map field's name.
- identifier_match = ProtoIdentifier.match(None, proto_source)
- if identifier_match is None:
- return None
- name = identifier_match.node
- proto_source = identifier_match.remaining_source.strip()
-
- if not proto_source.startswith("="):
- return None
- proto_source = proto_source[1:].strip()
-
- # Try to match the map field number.
- int_match = ProtoInt.match(None, proto_source)
- if int_match is None:
- return None
- number = int_match.node
- proto_source = int_match.remaining_source.strip()
-
- # Try to match map field options, if any.
- options = []
- if proto_source.startswith("["):
- proto_source = proto_source[1:].strip()
- end_bracket = proto_source.find("]")
- if end_bracket == -1:
- raise ValueError(
- f"Proto has invalid map field option syntax, cannot find ]: {proto_source}"
- )
- for option_part in proto_source[:end_bracket].strip().split(","):
- message_field_option_match = ProtoMessageFieldOption.match(
- None, option_part.strip()
- )
- if message_field_option_match is None:
- raise ValueError(
- f"Proto has invalid map field option syntax: {proto_source}"
- )
- options.append(message_field_option_match.node)
- proto_source = proto_source[end_bracket + 1 :].strip()
-
- if not proto_source.startswith(";"):
- raise ValueError(
- f"Proto has invalid map field syntax, missing ending ;:{proto_source}"
- )
-
- return ParsedProtoNode(
- ProtoMap(
- parent,
- key_type,
- value_type,
- name,
- number,
- enum_or_message_type_name,
- options,
- ),
- proto_source[1:].strip(),
- )
-
- def serialize(self) -> str:
- serialized_parts = [
- f"map",
- f"<{self.key_type.value},",
- ]
-
- if self.value_type == ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE:
- if self.enum_or_message_type_name is None:
- raise ValueError(
- f"Enum or message type name was not set for: {str(self)}"
- )
- serialized_parts.append(f"{self.enum_or_message_type_name.serialize()}>")
- else:
- serialized_parts.append(f"{self.value_type.value}>")
-
- serialized_parts = serialized_parts + [
- self.name.serialize(),
- "=",
- self.number.serialize(),
- ]
-
- if self.options:
- serialized_parts.append("[")
- serialized_parts.append(
- ", ".join(option.serialize() for option in self.options)
- )
- serialized_parts.append("]")
-
- return " ".join(serialized_parts) + ";"
-
- @staticmethod
- def diff(
- parent: Optional[ProtoNode], left: "ProtoMap", right: "ProtoMap"
- ) -> list["ProtoNodeDiff"]:
- if left is None and right is not None:
- return [ProtoMapAdded(parent, right)]
- elif left is not None and right is None:
- return [ProtoMapRemoved(parent, left)]
- elif left is None and right is None:
- return []
- elif left.name != right.name:
- return []
- elif left == right:
- return []
- diffs: list["ProtoNodeDiff"] = []
- return diffs
-
- @staticmethod
- def diff_sets(
- parent: Optional[ProtoNode], left: list["ProtoMap"], right: list["ProtoMap"]
- ) -> Sequence["ProtoNodeDiff"]:
- diffs: list[ProtoNodeDiff] = []
- left_names = set(o.name.identifier for o in left)
- right_names = set(o.name.identifier for o in right)
- for name in left_names - right_names:
- diffs.append(
- ProtoMapAdded(
- parent, next(i for i in left if i.name.identifier == name)
- )
- )
- for name in right_names - left_names:
- diffs.append(
- ProtoMapRemoved(
- parent, next(i for i in right if i.name.identifier == name)
- )
- )
- for name in left_names & right_names:
- left_enum = next(i for i in left if i.name.identifier == name)
- right_enum = next(i for i in right if i.name.identifier == name)
- diffs.extend(ProtoMap.diff(parent, left_enum, right_enum))
-
- return diffs
-
-
-class ProtoMapDiff(ProtoNodeDiff):
- def __init__(self, parent: Optional[ProtoNode], map: ProtoMap):
- self.parent = parent
- self.map = map
-
- def __eq__(self, other: object) -> bool:
- return isinstance(other, ProtoMapDiff) and self.map == other.map
-
- def __str__(self) -> str:
- return f"<{self.__class__.__name__} parent={self.parent} map={self.map}>"
-
-
-class ProtoMapAdded(ProtoMapDiff):
- def __eq__(self, other: object) -> bool:
- return super().__eq__(other) and isinstance(other, ProtoMapAdded)
-
-
-class ProtoMapRemoved(ProtoMapDiff):
- def __eq__(self, other: object) -> bool:
- return super().__eq__(other) and isinstance(other, ProtoMapRemoved)
-
class ProtoMessage(ProtoNode):
def __init__(
diff --git a/src/proto_oneof.py b/src/proto_oneof.py
new file mode 100644
index 0000000..5780710
--- /dev/null
+++ b/src/proto_oneof.py
@@ -0,0 +1,159 @@
+from typing import Optional, Sequence
+
+from src.proto_comment import (
+ ParsedProtoMultiLineCommentNode,
+ ParsedProtoSingleLineCommentNode,
+ ProtoComment,
+ ProtoMultiLineComment,
+ ProtoSingleLineComment,
+)
+from src.proto_identifier import ProtoIdentifier
+from src.proto_map import ProtoMap
+from src.proto_message_field import ParsedProtoMessageFieldNode, ProtoMessageField
+from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_option import ParsedProtoOptionNode, ProtoOption
+
+ProtoOneOfNodeTypes = (
+ ProtoOption | ProtoMessageField | ProtoSingleLineComment | ProtoMultiLineComment
+)
+ProtoParsedOneOfNodeTypes = (
+ ParsedProtoOptionNode
+ | ParsedProtoMessageFieldNode
+ | ParsedProtoSingleLineCommentNode
+ | ParsedProtoMultiLineCommentNode
+)
+
+
+class ParsedProtoOneOfNode(ParsedProtoNode):
+ node: "ProtoOneOf"
+ remaining_source: str
+
+
+class ProtoOneOf(ProtoNode):
+ def __init__(
+ self,
+ parent: Optional[ProtoNode],
+ name: ProtoIdentifier,
+ nodes: Sequence[ProtoOneOfNodeTypes],
+ ):
+ super().__init__(parent)
+ self.name = name
+ self.name.parent = self
+ self.nodes = nodes
+ for node in self.nodes:
+ node.parent = self
+
+ def __eq__(self, other) -> bool:
+ return self.name == other.name and self.nodes == other.nodes
+
+ def __str__(self) -> str:
+ return f"<{self.__class__.__name__} name={self.name}, nodes={self.nodes}>"
+
+ def __repr__(self) -> str:
+ return str(self)
+
+ def normalize(self) -> "ProtoOneOf":
+ non_comment_nodes = filter(
+ lambda n: not isinstance(n, ProtoComment), self.nodes
+ )
+ options = []
+ fields = []
+ for node in non_comment_nodes:
+ if isinstance(node, ProtoOption):
+ options.append(node.normalize())
+ elif (
+ isinstance(node, ProtoMessageField)
+ or isinstance(node, ProtoOneOf)
+ or isinstance(node, ProtoMap)
+ ):
+ fields.append(node.normalize())
+ else:
+ raise ValueError(
+ f"Can't sort message {self} node for normalizing: {node}"
+ )
+
+ sorted_nodes_for_normalizing = sorted(
+ options, key=lambda o: str(o.normalize())
+ ) + sorted(fields, key=lambda f: int(f.number))
+
+ return ProtoOneOf(
+ parent=self.parent,
+ name=self.name,
+ nodes=sorted_nodes_for_normalizing,
+ )
+
+ @staticmethod
+ def parse_partial_content(partial_oneof_content: str) -> ProtoParsedOneOfNodeTypes:
+ supported_types: list[type[ProtoOneOfNodeTypes]] = [
+ ProtoMessageField,
+ ProtoOption,
+ ProtoSingleLineComment,
+ ProtoMultiLineComment,
+ ]
+ for node_type in supported_types:
+ try:
+ match_result = node_type.match(None, partial_oneof_content)
+ except (ValueError, IndexError, TypeError):
+ raise ValueError(
+ f"Could not parse partial oneof content:\n{partial_oneof_content}"
+ )
+ if match_result is not None:
+ return match_result
+ raise ValueError(
+ f"Could not parse partial oneof content:\n{partial_oneof_content}"
+ )
+
+ @classmethod
+ def match(
+ cls, parent: Optional[ProtoNode], proto_source: str
+ ) -> Optional["ParsedProtoOneOfNode"]:
+ if not proto_source.startswith("oneof "):
+ return None
+
+ proto_source = proto_source[6:].strip()
+
+ match = ProtoIdentifier.match(None, proto_source)
+ if match is None:
+ raise ValueError(
+ f"Proto has invalid syntax, expecting identifier for oneof: {proto_source}"
+ )
+
+ oneof_name = match.node
+ proto_source = match.remaining_source.strip()
+
+ if not proto_source.startswith("{"):
+ raise ValueError(
+ f"Proto has invalid syntax, expecting opening curly brace: {proto_source}"
+ )
+
+ proto_source = proto_source[1:].strip()
+ parsed_tree = []
+ while proto_source:
+ # Remove empty statements.
+ if proto_source.startswith(";"):
+ proto_source = proto_source[1:].strip()
+ continue
+
+ if proto_source.startswith("}"):
+ proto_source = proto_source[1:].strip()
+ break
+
+ match_result = ProtoOneOf.parse_partial_content(proto_source)
+ parsed_tree.append(match_result.node)
+ proto_source = match_result.remaining_source.strip()
+
+ return ParsedProtoOneOfNode(
+ ProtoOneOf(parent, oneof_name, nodes=parsed_tree), proto_source
+ )
+
+ @property
+ def options(self) -> list[ProtoOption]:
+ return [node for node in self.nodes if isinstance(node, ProtoOption)]
+
+ def serialize(self) -> str:
+ serialize_parts = (
+ [f"oneof {self.name.serialize()} {{"]
+ + [n.serialize() for n in self.nodes]
+ + ["}"]
+ )
+ return "\n".join(serialize_parts)
diff --git a/test/BUILD.bazel b/test/BUILD.bazel
index a2954d7..f89b45f 100644
--- a/test/BUILD.bazel
+++ b/test/BUILD.bazel
@@ -125,6 +125,26 @@ py_test(
],
)
+py_test(
+ name = "proto_map_test",
+ srcs = ["proto_map_test.py"],
+ deps = [
+ "//src:proto_bool",
+ "//src:proto_comment",
+ "//src:proto_constant",
+ "//src:proto_enum",
+ "//src:proto_extend",
+ "//src:proto_extensions",
+ "//src:proto_identifier",
+ "//src:proto_int",
+ "//src:proto_map",
+ "//src:proto_message_field",
+ "//src:proto_option",
+ "//src:proto_reserved",
+ "//src:proto_string_literal",
+ ],
+)
+
py_test(
name = "proto_message_test",
srcs = ["proto_message_test.py"],
@@ -137,6 +157,7 @@ py_test(
"//src:proto_extensions",
"//src:proto_identifier",
"//src:proto_int",
+ "//src:proto_map",
"//src:proto_message",
"//src:proto_option",
"//src:proto_reserved",
@@ -151,7 +172,7 @@ py_test(
"//src:proto_extend",
"//src:proto_identifier",
"//src:proto_int",
- "//src:proto_message",
+ "//src:proto_message_field",
],
)
@@ -206,7 +227,9 @@ py_test(
"//src:proto_identifier",
"//src:proto_import",
"//src:proto_int",
+ "//src:proto_map",
"//src:proto_message",
+ "//src:proto_message_field",
"//src:proto_option",
"//src:proto_service",
"//src:proto_string_literal",
diff --git a/test/parser_test.py b/test/parser_test.py
index a9859c3..e5704bd 100644
--- a/test/parser_test.py
+++ b/test/parser_test.py
@@ -16,15 +16,12 @@
)
from src.proto_import import ProtoImport
from src.proto_int import ProtoInt, ProtoIntSign
-from src.proto_message import (
- ProtoMap,
- ProtoMapKeyTypesEnum,
- ProtoMapValueTypesEnum,
- ProtoMessage,
+from src.proto_map import ProtoMap, ProtoMapKeyTypesEnum, ProtoMapValueTypesEnum
+from src.proto_message import ProtoMessage, ProtoOneOf
+from src.proto_message_field import (
ProtoMessageField,
ProtoMessageFieldOption,
ProtoMessageFieldTypesEnum,
- ProtoOneOf,
)
from src.proto_option import ProtoOption
from src.proto_range import ProtoRange, ProtoRangeEnum
diff --git a/test/proto_extend_test.py b/test/proto_extend_test.py
index b77170b..0bec941 100644
--- a/test/proto_extend_test.py
+++ b/test/proto_extend_test.py
@@ -4,7 +4,7 @@
from src.proto_extend import ProtoExtend
from src.proto_identifier import ProtoEnumOrMessageIdentifier, ProtoIdentifier
from src.proto_int import ProtoInt, ProtoIntSign
-from src.proto_message import ProtoMessageField, ProtoMessageFieldTypesEnum
+from src.proto_message_field import ProtoMessageField, ProtoMessageFieldTypesEnum
class ExtendTest(unittest.TestCase):
diff --git a/test/proto_map_test.py b/test/proto_map_test.py
new file mode 100644
index 0000000..f45d214
--- /dev/null
+++ b/test/proto_map_test.py
@@ -0,0 +1,100 @@
+import unittest
+
+from src.proto_constant import ProtoConstant
+from src.proto_identifier import (
+ ProtoEnumOrMessageIdentifier,
+ ProtoFullIdentifier,
+ ProtoIdentifier,
+)
+from src.proto_int import ProtoInt, ProtoIntSign
+from src.proto_map import ProtoMap, ProtoMapKeyTypesEnum, ProtoMapValueTypesEnum
+from src.proto_message_field import ProtoMessageFieldOption
+from src.proto_string_literal import ProtoStringLiteral
+
+
+class MapTest(unittest.TestCase):
+ maxDiff = None
+
+ def test_simple_map(self):
+ parsed_map_simple = ProtoMap.match(
+ None, "map my_map = 10;"
+ )
+ self.assertEqual(
+ parsed_map_simple.node,
+ ProtoMap(
+ None,
+ ProtoMapKeyTypesEnum.SFIXED64,
+ ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
+ ProtoIdentifier(None, "my_map"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ [],
+ ),
+ )
+
+ def test_map_without_spaces(self):
+ map_without_spaces = ProtoMap.match(
+ None, "map my_map = 10;"
+ )
+ self.assertEqual(
+ map_without_spaces.node,
+ ProtoMap(
+ None,
+ ProtoMapKeyTypesEnum.SFIXED64,
+ ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
+ ProtoIdentifier(None, "my_map"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ [],
+ ),
+ )
+
+ def test_map_with_options(self):
+ parsed_map_simple = ProtoMap.match(
+ None,
+ "map my_map = 10 [ java_package = 'com.example.foo', baz.bat = 48 ];",
+ )
+ self.assertEqual(parsed_map_simple.node.key_type, ProtoMapKeyTypesEnum.SFIXED64)
+ self.assertEqual(
+ parsed_map_simple.node.value_type, ProtoMapValueTypesEnum.ENUM_OR_MESSAGE
+ )
+ self.assertEqual(parsed_map_simple.node.name, ProtoIdentifier(None, "my_map"))
+ self.assertEqual(
+ parsed_map_simple.node.number, ProtoInt(None, 10, ProtoIntSign.POSITIVE)
+ )
+ self.assertEqual(
+ parsed_map_simple.node.enum_or_message_type_name,
+ ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ )
+ self.assertEqual(
+ parsed_map_simple.node.options,
+ [
+ ProtoMessageFieldOption(
+ None,
+ ProtoIdentifier(None, "java_package"),
+ ProtoConstant(None, ProtoStringLiteral(None, "com.example.foo")),
+ ),
+ ProtoMessageFieldOption(
+ None,
+ ProtoFullIdentifier(None, "baz.bat"),
+ ProtoConstant(None, ProtoInt(None, 48, ProtoIntSign.POSITIVE)),
+ ),
+ ],
+ )
+
+ def test_map_message_value(self):
+ parsed_map_simple = ProtoMap.match(
+ None, "map string_map = 11;"
+ )
+ self.assertEqual(
+ parsed_map_simple.node,
+ ProtoMap(
+ None,
+ ProtoMapKeyTypesEnum.STRING,
+ ProtoMapValueTypesEnum.STRING,
+ ProtoIdentifier(None, "string_map"),
+ ProtoInt(None, 11, ProtoIntSign.POSITIVE),
+ None,
+ [],
+ ),
+ )
diff --git a/test/proto_message_test.py b/test/proto_message_test.py
index 3153c72..2a62886 100644
--- a/test/proto_message_test.py
+++ b/test/proto_message_test.py
@@ -13,10 +13,8 @@
ProtoIdentifier,
)
from src.proto_int import ProtoInt, ProtoIntSign
+from src.proto_map import ProtoMap, ProtoMapKeyTypesEnum, ProtoMapValueTypesEnum
from src.proto_message import (
- ProtoMap,
- ProtoMapKeyTypesEnum,
- ProtoMapValueTypesEnum,
ProtoMessage,
ProtoMessageAdded,
ProtoMessageRemoved,
From fcc4a3d7ee77bb2a89cb3a4ec975eed636e9c80b Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sat, 18 Feb 2023 23:10:42 -0500
Subject: [PATCH 13/35] Pin bazel version to 6.0.0 (#70)
---
.bazelversion | 1 +
1 file changed, 1 insertion(+)
create mode 100644 .bazelversion
diff --git a/.bazelversion b/.bazelversion
new file mode 100644
index 0000000..09b254e
--- /dev/null
+++ b/.bazelversion
@@ -0,0 +1 @@
+6.0.0
From a7eecbd497d11a168bf383c2f4e3068441b78fa1 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sun, 19 Feb 2023 19:52:55 -0500
Subject: [PATCH 14/35] Pull binaries into src.util (#71)
---
README.md | 2 +-
src/BUILD.bazel | 47 +------------------
src/util/BUILD.bazel | 46 ++++++++++++++++++
src/{ => util}/compatibility_checker.py | 2 +-
src/{ => util}/parser.py | 0
test/BUILD.bazel | 43 -----------------
test/compatibility_checker_binary_test.sh | 4 --
test/util/BUILD.bazel | 44 +++++++++++++++++
.../util/compatibility_checker_binary_test.sh | 4 ++
test/{ => util}/parser_binary_test.sh | 4 +-
test/{ => util}/parser_test.py | 2 +-
11 files changed, 100 insertions(+), 98 deletions(-)
create mode 100644 src/util/BUILD.bazel
rename src/{ => util}/compatibility_checker.py (96%)
rename src/{ => util}/parser.py (100%)
delete mode 100755 test/compatibility_checker_binary_test.sh
create mode 100644 test/util/BUILD.bazel
create mode 100755 test/util/compatibility_checker_binary_test.sh
rename test/{ => util}/parser_binary_test.sh (80%)
rename test/{ => util}/parser_test.py (99%)
diff --git a/README.md b/README.md
index bd8333d..b6e911f 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ py_library(
Then, in your Python code, use the parser:
```python
-from src.parser import ParseError, Parser
+from src.util.parser import ParseError, Parser
with open("your.proto", "r") as proto_file:
parsed_proto = Parser.loads(proto_file.read())
diff --git a/src/BUILD.bazel b/src/BUILD.bazel
index 899a7d5..13dfe8f 100644
--- a/src/BUILD.bazel
+++ b/src/BUILD.bazel
@@ -1,4 +1,4 @@
-load("@rules_python//python:defs.bzl", "py_binary", "py_library")
+load("@rules_python//python:defs.bzl", "py_library")
py_library(
name = "proto_node",
@@ -257,48 +257,3 @@ py_library(
":proto_syntax",
],
)
-
-py_library(
- name = "parser",
- srcs = ["parser.py"],
- visibility = ["//visibility:public"],
- deps = [
- ":proto_enum",
- ":proto_extend",
- ":proto_file",
- ":proto_import",
- ":proto_message",
- ":proto_node",
- ":proto_option",
- ":proto_package",
- ":proto_service",
- ":proto_syntax",
- ],
-)
-
-py_binary(
- name = "parser_binary",
- srcs = ["parser.py"],
- main = "parser.py",
- visibility = ["//visibility:public"],
- deps = [":parser"],
-)
-
-py_library(
- name = "compatibility_checker",
- srcs = ["compatibility_checker.py"],
- visibility = ["//visibility:public"],
- deps = [
- ":parser",
- ":proto_file",
- ":proto_node",
- ],
-)
-
-py_binary(
- name = "compatibility_checker_binary",
- srcs = ["compatibility_checker.py"],
- main = "compatibility_checker.py",
- visibility = ["//visibility:public"],
- deps = [":compatibility_checker"],
-)
diff --git a/src/util/BUILD.bazel b/src/util/BUILD.bazel
new file mode 100644
index 0000000..827decd
--- /dev/null
+++ b/src/util/BUILD.bazel
@@ -0,0 +1,46 @@
+load("@rules_python//python:defs.bzl", "py_binary", "py_library")
+
+py_library(
+ name = "parser",
+ srcs = ["parser.py"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//src:proto_enum",
+ "//src:proto_extend",
+ "//src:proto_file",
+ "//src:proto_import",
+ "//src:proto_message",
+ "//src:proto_node",
+ "//src:proto_option",
+ "//src:proto_package",
+ "//src:proto_service",
+ "//src:proto_syntax",
+ ],
+)
+
+py_binary(
+ name = "parser_binary",
+ srcs = ["parser.py"],
+ main = "parser.py",
+ visibility = ["//visibility:public"],
+ deps = [":parser"],
+)
+
+py_library(
+ name = "compatibility_checker",
+ srcs = ["compatibility_checker.py"],
+ visibility = ["//visibility:public"],
+ deps = [
+ ":parser",
+ "//src:proto_file",
+ "//src:proto_node",
+ ],
+)
+
+py_binary(
+ name = "compatibility_checker_binary",
+ srcs = ["compatibility_checker.py"],
+ main = "compatibility_checker.py",
+ visibility = ["//visibility:public"],
+ deps = [":compatibility_checker"],
+)
diff --git a/src/compatibility_checker.py b/src/util/compatibility_checker.py
similarity index 96%
rename from src/compatibility_checker.py
rename to src/util/compatibility_checker.py
index 8971f72..beb2199 100644
--- a/src/compatibility_checker.py
+++ b/src/util/compatibility_checker.py
@@ -2,10 +2,10 @@
from dataclasses import dataclass
from typing import Type
-from src.parser import Parser
from src.proto_file import ProtoFile
from src.proto_message import ProtoMessageAdded
from src.proto_node import ProtoNodeDiff
+from src.util.parser import Parser
@dataclass
diff --git a/src/parser.py b/src/util/parser.py
similarity index 100%
rename from src/parser.py
rename to src/util/parser.py
diff --git a/test/BUILD.bazel b/test/BUILD.bazel
index f89b45f..47cd15a 100644
--- a/test/BUILD.bazel
+++ b/test/BUILD.bazel
@@ -213,30 +213,6 @@ py_test(
],
)
-py_test(
- name = "parser_test",
- srcs = ["parser_test.py"],
- deps = [
- "//src:parser",
- "//src:proto_comment",
- "//src:proto_constant",
- "//src:proto_enum",
- "//src:proto_extend",
- "//src:proto_extensions",
- "//src:proto_float",
- "//src:proto_identifier",
- "//src:proto_import",
- "//src:proto_int",
- "//src:proto_map",
- "//src:proto_message",
- "//src:proto_message_field",
- "//src:proto_option",
- "//src:proto_service",
- "//src:proto_string_literal",
- "//src:proto_syntax",
- ],
-)
-
py_test(
name = "proto_file_test",
srcs = ["proto_file_test.py"],
@@ -244,22 +220,3 @@ py_test(
"//src:proto_file",
],
)
-
-sh_test(
- name = "parser_binary_test",
- srcs = ["parser_binary_test.sh"],
- data = [
- "//src:parser_binary",
- "//test/resources:all_protos",
- "@com_google_protobuf//:all_proto",
- ],
-)
-
-sh_test(
- name = "compatibility_checker_binary_test",
- srcs = ["compatibility_checker_binary_test.sh"],
- data = [
- "//src:compatibility_checker_binary",
- "//test/resources:all_protos",
- ],
-)
diff --git a/test/compatibility_checker_binary_test.sh b/test/compatibility_checker_binary_test.sh
deleted file mode 100755
index 0f01063..0000000
--- a/test/compatibility_checker_binary_test.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env bash
-set -euxo pipefail
-
-./src/compatibility_checker_binary ./test/resources/single_message.proto ./test/resources/empty.proto
diff --git a/test/util/BUILD.bazel b/test/util/BUILD.bazel
new file mode 100644
index 0000000..5e57fb2
--- /dev/null
+++ b/test/util/BUILD.bazel
@@ -0,0 +1,44 @@
+load("@rules_python//python:defs.bzl", "py_test")
+
+py_test(
+ name = "parser_test",
+ srcs = ["parser_test.py"],
+ deps = [
+ "//src:proto_comment",
+ "//src:proto_constant",
+ "//src:proto_enum",
+ "//src:proto_extend",
+ "//src:proto_extensions",
+ "//src:proto_float",
+ "//src:proto_identifier",
+ "//src:proto_import",
+ "//src:proto_int",
+ "//src:proto_map",
+ "//src:proto_message",
+ "//src:proto_message_field",
+ "//src:proto_option",
+ "//src:proto_service",
+ "//src:proto_string_literal",
+ "//src:proto_syntax",
+ "//src/util:parser",
+ ],
+)
+
+sh_test(
+ name = "parser_binary_test",
+ srcs = ["parser_binary_test.sh"],
+ data = [
+ "//src/util:parser_binary",
+ "//test/resources:all_protos",
+ "@com_google_protobuf//:all_proto",
+ ],
+)
+
+sh_test(
+ name = "compatibility_checker_binary_test",
+ srcs = ["compatibility_checker_binary_test.sh"],
+ data = [
+ "//src/util:compatibility_checker_binary",
+ "//test/resources:all_protos",
+ ],
+)
diff --git a/test/util/compatibility_checker_binary_test.sh b/test/util/compatibility_checker_binary_test.sh
new file mode 100755
index 0000000..da18716
--- /dev/null
+++ b/test/util/compatibility_checker_binary_test.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+set -euxo pipefail
+
+./src/util/compatibility_checker_binary ./test/resources/single_message.proto ./test/resources/empty.proto
diff --git a/test/parser_binary_test.sh b/test/util/parser_binary_test.sh
similarity index 80%
rename from test/parser_binary_test.sh
rename to test/util/parser_binary_test.sh
index d3885ef..b0a817d 100755
--- a/test/parser_binary_test.sh
+++ b/test/util/parser_binary_test.sh
@@ -5,12 +5,12 @@ echo "Local protos:"
LOCAL_PROTOS=$(find ./test/resources -name "*.proto" | sort)
for f in $LOCAL_PROTOS; do
echo $f
- ./src/parser_binary $f > /dev/null
+ ./src/util/parser_binary $f > /dev/null
done
echo "Google protos:"
GOOGLE_PROTOS=$(find ./external/com_google_protobuf/src/google/protobuf -name "*.proto" | xargs grep --files-without-match "proto2" | sort)
for f in $GOOGLE_PROTOS; do
echo $f
- ./src/parser_binary $f > /dev/null
+ ./src/util/parser_binary $f > /dev/null
done
diff --git a/test/parser_test.py b/test/util/parser_test.py
similarity index 99%
rename from test/parser_test.py
rename to test/util/parser_test.py
index e5704bd..08c9470 100644
--- a/test/parser_test.py
+++ b/test/util/parser_test.py
@@ -1,7 +1,6 @@
import unittest
from textwrap import dedent
-from src.parser import ParseError, Parser
from src.proto_bool import ProtoBool
from src.proto_comment import ProtoSingleLineComment
from src.proto_constant import ProtoConstant
@@ -29,6 +28,7 @@
from src.proto_service import ProtoService, ProtoServiceRPC
from src.proto_string_literal import ProtoStringLiteral
from src.proto_syntax import ProtoSyntaxType
+from src.util.parser import ParseError, Parser
class IntTest(unittest.TestCase):
From 809a684c370ecce64a127cea4c2b9f3dc3e62239 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Mon, 20 Feb 2023 18:58:34 -0500
Subject: [PATCH 15/35] In messages, support diffing message field changes
(#72)
- Change semantics around enum value diffs: we no longer support "value
has changed number" diffs. Instead, we emit one EnumValueRemoved at the
prior number, and one EnumValueAdded at the new number.
- Follow same semantics for message field diffs
- We used to pass left/right into diff methods. To make the meaning
unambiguous, we change this to before/after, and correct a _ton_ of
places we were using this inconsistently.
---
TODO.md | 2 +-
src/proto_enum.py | 118 ++++----
src/proto_import.py | 36 +--
src/proto_map.py | 42 +--
src/proto_message.py | 58 ++--
src/proto_message_field.py | 102 ++++++-
src/proto_option.py | 70 ++---
src/proto_package.py | 38 +--
src/proto_syntax.py | 16 +-
src/util/compatibility_checker.py | 10 +-
test/proto_enum_test.py | 41 +--
test/proto_message_field_test.py | 277 +++++++++++++++++-
test/proto_message_test.py | 28 +-
test/proto_option_test.py | 34 +--
test/proto_package_test.py | 12 +-
.../util/compatibility_checker_binary_test.sh | 2 +-
16 files changed, 633 insertions(+), 253 deletions(-)
diff --git a/TODO.md b/TODO.md
index e738ea0..0ade4bf 100644
--- a/TODO.md
+++ b/TODO.md
@@ -74,7 +74,7 @@
- [ ] Message-level diffs
- [x] Additions/removals
- [x] Option changes
- - [ ] Field changes
+ - [x] Field changes
- [ ] Reserved changes
- [ ] Nested enum changes
- [ ] Nested message changes
diff --git a/src/proto_enum.py b/src/proto_enum.py
index a5e1f47..c1f682c 100644
--- a/src/proto_enum.py
+++ b/src/proto_enum.py
@@ -157,61 +157,49 @@ def serialize(self) -> str:
@staticmethod
def diff(
- enum: "ProtoEnum", left: "ProtoEnumValue", right: "ProtoEnumValue"
+ enum: "ProtoEnum",
+ before: Optional["ProtoEnumValue"],
+ after: Optional["ProtoEnumValue"],
) -> Sequence["ProtoNodeDiff"]:
- if left is None and right is not None:
- return [ProtoEnumValueAdded(right)]
- elif left is not None and right is None:
- return [ProtoEnumValueRemoved(left)]
- elif left is None and right is None:
- return []
- elif left.identifier != right.identifier:
- return []
- elif left == right:
- return []
diffs: list["ProtoNodeDiff"] = []
# TODO: scope these diffs under ProtoEnumValue
- diffs.extend(ProtoEnumValueOption.diff_sets(left.options, right.options))
- diffs.append(ProtoEnumValueValueChanged(enum, right, left.value))
+ if before is None or after is None:
+ if after is not None:
+ diffs.append(ProtoEnumValueAdded(enum, after))
+ elif before is not None:
+ diffs.append(ProtoEnumValueRemoved(enum, before))
+ else:
+ if before.identifier != after.identifier:
+ diffs.append(ProtoEnumValueNameChanged(enum, before, after.identifier))
+ else:
+ raise ValueError(
+ f"Don't know how to handle diff between enums whose names aren't identical: {before}, {after}"
+ )
+ diffs.extend(ProtoEnumValueOption.diff_sets(before.options, after.options))
return diffs
@staticmethod
def diff_sets(
- enum: "ProtoEnum", left: list["ProtoEnumValue"], right: list["ProtoEnumValue"]
+ enum: "ProtoEnum", before: list["ProtoEnumValue"], after: list["ProtoEnumValue"]
) -> list["ProtoNodeDiff"]:
diffs: list[ProtoNodeDiff] = []
- left_names = set(o.identifier.identifier for o in left)
- left_values = set(int(o.value) for o in left)
- right_names = set(o.identifier.identifier for o in right)
- right_values = set(int(o.value) for o in right)
-
- for name in left_names - right_names:
- # Check to see if this is a renamed field number.
- left_value = next(i for i in left if i.identifier.identifier == name)
- if int(left_value.value) in right_values:
- # This is a renamed field number.
- right_value = next(
- i for i in right if int(i.value) == int(left_value.value)
- )
- diffs.append(
- ProtoEnumValueNameChanged(enum, right_value, left_value.identifier)
- )
- else:
- diffs.append(ProtoEnumValueAdded(enum, left_value))
- for name in right_names - left_names:
- # Check to see if this is a renamed field number.
- right_value = next(i for i in right if i.identifier.identifier == name)
- if int(right_value.value) not in left_values:
- diffs.append(
- ProtoEnumValueRemoved(
- enum, next(i for i in right if i.identifier.identifier == name)
- )
+
+ before_number_to_enum_values = {int(mf.value): mf for mf in before}
+ after_number_to_enum_values = {int(mf.value): mf for mf in after}
+ all_numbers = sorted(
+ set(before_number_to_enum_values.keys()).union(
+ set(after_number_to_enum_values.keys())
+ )
+ )
+ for number in all_numbers:
+ diffs.extend(
+ ProtoEnumValue.diff(
+ enum,
+ before_number_to_enum_values.get(number, None),
+ after_number_to_enum_values.get(number, None),
)
- for name in left_names & right_names:
- left_enum_value = next(i for i in left if i.identifier.identifier == name)
- right_enum_value = next(i for i in right if i.identifier.identifier == name)
- diffs.extend(ProtoEnumValue.diff(enum, left_enum_value, right_enum_value))
+ )
return diffs
@@ -329,42 +317,42 @@ def serialize(self) -> str:
return "\n".join(serialize_parts)
@staticmethod
- def diff(left: "ProtoEnum", right: "ProtoEnum") -> list["ProtoNodeDiff"]:
- if left is None and right is not None:
- return [ProtoEnumAdded(right)]
- elif left is not None and right is None:
- return [ProtoEnumRemoved(left)]
- elif left is None and right is None:
+ def diff(before: "ProtoEnum", after: "ProtoEnum") -> list["ProtoNodeDiff"]:
+ if before is None and after is not None:
+ return [ProtoEnumAdded(after)]
+ elif before is not None and after is None:
+ return [ProtoEnumRemoved(before)]
+ elif before is None and after is None:
return []
- elif left.name != right.name:
+ elif before.name != after.name:
return []
- elif left == right:
+ elif before == after:
return []
diffs: list[ProtoNodeDiff] = []
# TODO: scope these diffs under ProtoEnum
- diffs.extend(ProtoOption.diff_sets(left.options, right.options))
- diffs.extend(ProtoEnumValue.diff_sets(left, left.values, right.values))
+ diffs.extend(ProtoOption.diff_sets(before.options, after.options))
+ diffs.extend(ProtoEnumValue.diff_sets(before, before.values, after.values))
return diffs
@staticmethod
def diff_sets(
- left: list["ProtoEnum"], right: list["ProtoEnum"]
+ before: list["ProtoEnum"], after: list["ProtoEnum"]
) -> list["ProtoNodeDiff"]:
diffs: list[ProtoNodeDiff] = []
- left_names = set(o.name.identifier for o in left)
- right_names = set(o.name.identifier for o in right)
- for name in left_names - right_names:
+ before_names = set(o.name.identifier for o in before)
+ after_names = set(o.name.identifier for o in after)
+ for name in before_names - after_names:
diffs.append(
- ProtoEnumAdded(next(i for i in left if i.name.identifier == name))
+ ProtoEnumRemoved(next(i for i in before if i.name.identifier == name))
)
- for name in right_names - left_names:
+ for name in after_names - before_names:
diffs.append(
- ProtoEnumRemoved(next(i for i in right if i.name.identifier == name))
+ ProtoEnumAdded(next(i for i in after if i.name.identifier == name))
)
- for name in left_names & right_names:
- left_enum = next(i for i in left if i.name.identifier == name)
- right_enum = next(i for i in right if i.name.identifier == name)
- diffs.extend(ProtoEnum.diff(left_enum, right_enum))
+ for name in before_names & after_names:
+ before_enum = next(i for i in before if i.name.identifier == name)
+ after_enum = next(i for i in after if i.name.identifier == name)
+ diffs.extend(ProtoEnum.diff(before_enum, after_enum))
return diffs
diff --git a/src/proto_import.py b/src/proto_import.py
index fdd0ba9..4cda9a3 100644
--- a/src/proto_import.py
+++ b/src/proto_import.py
@@ -86,26 +86,26 @@ def serialize(self) -> str:
@staticmethod
def diff_sets(
- left: list["ProtoImport"], right: list["ProtoImport"]
+ before: list["ProtoImport"], after: list["ProtoImport"]
) -> list["ProtoNodeDiff"]:
diffs: list[ProtoNodeDiff] = []
- left_names = set(i.path for i in left)
- right_names = set(i.path for i in right)
- for name in left_names - right_names:
- diffs.append(ProtoImportAdded(next(i for i in left if i.path == name)))
- for name in right_names - left_names:
- diffs.append(ProtoImportRemoved(next(i for i in right if i.path == name)))
- for name in left_names & right_names:
- left_import = next(i for i in left if i.path == name)
- right_import = next(i for i in right if i.path == name)
- if left_import.weak and not right_import.weak:
- diffs.append(ProtoImportMadeWeak(right_import))
- if not left_import.weak and right_import.weak:
- diffs.append(ProtoImportMadeNonWeak(right_import))
- if left_import.public and not right_import.public:
- diffs.append(ProtoImportMadePublic(right_import))
- if not left_import.public and right_import.public:
- diffs.append(ProtoImportMadeNonPublic(right_import))
+ before_names = set(i.path for i in before)
+ after_names = set(i.path for i in after)
+ for name in before_names - after_names:
+ diffs.append(ProtoImportRemoved(next(i for i in before if i.path == name)))
+ for name in after_names - before_names:
+ diffs.append(ProtoImportAdded(next(i for i in after if i.path == name)))
+ for name in before_names & after_names:
+ before_import = next(i for i in before if i.path == name)
+ after_import = next(i for i in after if i.path == name)
+ if before_import.weak and not after_import.weak:
+ diffs.append(ProtoImportMadeNonWeak(after_import))
+ elif not before_import.weak and after_import.weak:
+ diffs.append(ProtoImportMadeWeak(after_import))
+ if before_import.public and not after_import.public:
+ diffs.append(ProtoImportMadeNonPublic(after_import))
+ elif not before_import.public and after_import.public:
+ diffs.append(ProtoImportMadePublic(after_import))
return diffs
diff --git a/src/proto_map.py b/src/proto_map.py
index 9d73594..129b46b 100644
--- a/src/proto_map.py
+++ b/src/proto_map.py
@@ -219,44 +219,44 @@ def serialize(self) -> str:
@staticmethod
def diff(
- parent: Optional[ProtoNode], left: "ProtoMap", right: "ProtoMap"
+ parent: Optional[ProtoNode], before: "ProtoMap", after: "ProtoMap"
) -> list["ProtoNodeDiff"]:
- if left is None and right is not None:
- return [ProtoMapAdded(parent, right)]
- elif left is not None and right is None:
- return [ProtoMapRemoved(parent, left)]
- elif left is None and right is None:
+ if before is None and after is not None:
+ return [ProtoMapAdded(parent, after)]
+ elif before is not None and after is None:
+ return [ProtoMapRemoved(parent, before)]
+ elif before is None and after is None:
return []
- elif left.name != right.name:
+ elif before.name != after.name:
return []
- elif left == right:
+ elif before == after:
return []
diffs: list["ProtoNodeDiff"] = []
return diffs
@staticmethod
def diff_sets(
- parent: Optional[ProtoNode], left: list["ProtoMap"], right: list["ProtoMap"]
+ parent: Optional[ProtoNode], before: list["ProtoMap"], after: list["ProtoMap"]
) -> Sequence["ProtoNodeDiff"]:
diffs: list[ProtoNodeDiff] = []
- left_names = set(o.name.identifier for o in left)
- right_names = set(o.name.identifier for o in right)
- for name in left_names - right_names:
+ before_names = set(o.name.identifier for o in before)
+ after_names = set(o.name.identifier for o in after)
+ for name in before_names - after_names:
diffs.append(
- ProtoMapAdded(
- parent, next(i for i in left if i.name.identifier == name)
+ ProtoMapRemoved(
+ parent, next(i for i in before if i.name.identifier == name)
)
)
- for name in right_names - left_names:
+ for name in after_names - before_names:
diffs.append(
- ProtoMapRemoved(
- parent, next(i for i in right if i.name.identifier == name)
+ ProtoMapAdded(
+ parent, next(i for i in after if i.name.identifier == name)
)
)
- for name in left_names & right_names:
- left_enum = next(i for i in left if i.name.identifier == name)
- right_enum = next(i for i in right if i.name.identifier == name)
- diffs.extend(ProtoMap.diff(parent, left_enum, right_enum))
+ for name in before_names & after_names:
+ before_enum = next(i for i in before if i.name.identifier == name)
+ after_enum = next(i for i in after if i.name.identifier == name)
+ diffs.extend(ProtoMap.diff(parent, before_enum, after_enum))
return diffs
diff --git a/src/proto_message.py b/src/proto_message.py
index 8c084c9..01277a7 100644
--- a/src/proto_message.py
+++ b/src/proto_message.py
@@ -160,6 +160,10 @@ def options(self) -> list[ProtoOption]:
def maps(self) -> list[ProtoMap]:
return [node for node in self.nodes if isinstance(node, ProtoMap)]
+ @property
+ def message_fields(self) -> list[ProtoMessageField]:
+ return [node for node in self.nodes if isinstance(node, ProtoMessageField)]
+
def serialize(self) -> str:
serialize_parts = (
[f"message {self.name.serialize()} {{"]
@@ -169,43 +173,51 @@ def serialize(self) -> str:
return "\n".join(serialize_parts)
@staticmethod
- def diff(left: "ProtoMessage", right: "ProtoMessage") -> Sequence["ProtoNodeDiff"]:
- if left is None and right is not None:
- return [ProtoMessageAdded(right)]
- elif left is not None and right is None:
- return [ProtoMessageRemoved(left)]
- elif left is None and right is None:
+ def diff(
+ before: "ProtoMessage", after: "ProtoMessage"
+ ) -> Sequence["ProtoNodeDiff"]:
+ if before is None and after is not None:
+ return [ProtoMessageAdded(after)]
+ elif before is not None and after is None:
+ return [ProtoMessageRemoved(before)]
+ elif before is None and after is None:
return []
- elif left.name != right.name:
+ elif before.name != after.name:
return []
- elif left == right:
+ elif before == after:
return []
diffs: list[ProtoNodeDiff] = []
- diffs.extend(ProtoOption.diff_sets(left.options, right.options))
- # diffs.extend(ProtoOneOf.diff_sets(left, left.oneofs, right.oneofs))
- diffs.extend(ProtoMap.diff_sets(left, left.maps, right.maps))
- # diffs.extend(ProtoMessageField.diff_sets(left, left.message_fields, right.message_fields))
+ diffs.extend(ProtoOption.diff_sets(before.options, after.options))
+ # diffs.extend(ProtoOneOf.diff_sets(before, before.oneofs, after.oneofs))
+ diffs.extend(ProtoMap.diff_sets(before, before.maps, after.maps))
+ diffs.extend(
+ ProtoMessageField.diff_sets(
+ before, before.message_fields, after.message_fields
+ )
+ )
return diffs
@staticmethod
def diff_sets(
- left: list["ProtoMessage"], right: list["ProtoMessage"]
+ before: list["ProtoMessage"], after: list["ProtoMessage"]
) -> Sequence["ProtoNodeDiff"]:
diffs: list[ProtoNodeDiff] = []
- left_names = set(o.name.identifier for o in left)
- right_names = set(o.name.identifier for o in right)
- for name in left_names - right_names:
+ before_names = set(o.name.identifier for o in before)
+ after_names = set(o.name.identifier for o in after)
+ for name in before_names - after_names:
diffs.append(
- ProtoMessageAdded(next(i for i in left if i.name.identifier == name))
+ ProtoMessageRemoved(
+ next(i for i in before if i.name.identifier == name)
+ )
)
- for name in right_names - left_names:
+ for name in after_names - before_names:
diffs.append(
- ProtoMessageRemoved(next(i for i in right if i.name.identifier == name))
+ ProtoMessageAdded(next(i for i in after if i.name.identifier == name))
)
- for name in left_names & right_names:
- left_enum = next(i for i in left if i.name.identifier == name)
- right_enum = next(i for i in right if i.name.identifier == name)
- diffs.extend(ProtoMessage.diff(left_enum, right_enum))
+ for name in before_names & after_names:
+ before_enum = next(i for i in before if i.name.identifier == name)
+ after_enum = next(i for i in after if i.name.identifier == name)
+ diffs.extend(ProtoMessage.diff(before_enum, after_enum))
return diffs
diff --git a/src/proto_message_field.py b/src/proto_message_field.py
index 390cef8..aa5c7c2 100644
--- a/src/proto_message_field.py
+++ b/src/proto_message_field.py
@@ -1,10 +1,10 @@
from enum import Enum
-from typing import Optional
+from typing import Optional, Sequence
from src.proto_enum import ParsedProtoEnumValueOptionNode, ProtoEnumValueOption
from src.proto_identifier import ProtoEnumOrMessageIdentifier, ProtoIdentifier
from src.proto_int import ProtoInt
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
class ParsedProtoMessageFieldOptionNode(ParsedProtoEnumValueOptionNode):
@@ -241,3 +241,101 @@ def serialize(self) -> str:
serialized_parts.append("]")
return " ".join(serialized_parts) + ";"
+
+ @staticmethod
+ def diff(
+ parent: "ProtoNode",
+ before: Optional["ProtoMessageField"],
+ after: Optional["ProtoMessageField"],
+ ) -> Sequence["ProtoNodeDiff"]:
+ # TODO: scope these diffs under ProtoMessageField
+ diffs: list["ProtoNodeDiff"] = []
+ if before is None or after is None:
+ if after is not None:
+ diffs.append(ProtoMessageFieldAdded(parent, after))
+ elif before is not None:
+ diffs.append(ProtoMessageFieldRemoved(parent, before))
+ else:
+ if before.name != after.name:
+ diffs.append(ProtoMessageFieldNameChanged(parent, before, after.name))
+ if before.number != after.number:
+ raise ValueError(
+ f"Don't know how to handle diff between message fields whose names are identical: {before}, {after}"
+ )
+ diffs.extend(
+ ProtoMessageFieldOption.diff_sets(before.options, after.options)
+ )
+ return diffs
+
+ @staticmethod
+ def diff_sets(
+ parent: "ProtoNode",
+ before: list["ProtoMessageField"],
+ after: list["ProtoMessageField"],
+ ) -> list["ProtoNodeDiff"]:
+ diffs: list[ProtoNodeDiff] = []
+
+ before_number_to_fields = {int(mf.number): mf for mf in before}
+ after_number_to_fields = {int(mf.number): mf for mf in after}
+ all_numbers = sorted(
+ set(before_number_to_fields.keys()).union(
+ set(after_number_to_fields.keys())
+ )
+ )
+ for number in all_numbers:
+ diffs.extend(
+ ProtoMessageField.diff(
+ parent,
+ before_number_to_fields.get(number, None),
+ after_number_to_fields.get(number, None),
+ )
+ )
+
+ return diffs
+
+
+class ProtoMessageFieldDiff(ProtoNodeDiff):
+ def __init__(self, message: "ProtoNode", message_field: "ProtoMessageField"):
+ super().__init__()
+ self.message = message
+ self.message_field = message_field
+
+ def __eq__(self, other: object) -> bool:
+ return (
+ super().__eq__(other)
+ and isinstance(other, ProtoMessageFieldDiff)
+ and self.message == other.message
+ and self.message_field == other.message_field
+ )
+
+ def __str__(self) -> str:
+ return f"<{self.__class__.__name__} message={self.message} message_field={self.message_field}>"
+
+
+class ProtoMessageFieldAdded(ProtoMessageFieldDiff):
+ pass
+
+
+class ProtoMessageFieldRemoved(ProtoMessageFieldDiff):
+ pass
+
+
+class ProtoMessageFieldNameChanged(ProtoMessageFieldDiff):
+ def __init__(
+ self,
+ message: ProtoNode,
+ message_field: ProtoMessageField,
+ new_name: ProtoIdentifier,
+ ):
+ super().__init__(message, message_field)
+ self.new_name = new_name
+
+ def __eq__(self, other: object) -> bool:
+ return (
+ super().__eq__(other)
+ and isinstance(other, ProtoMessageFieldNameChanged)
+ and self.new_name == other.new_name
+ )
+
+ def __str__(self) -> str:
+ return f""
diff --git a/src/proto_option.py b/src/proto_option.py
index 312dcac..4090378 100644
--- a/src/proto_option.py
+++ b/src/proto_option.py
@@ -123,38 +123,40 @@ def serialize(self) -> str:
return f"option {self.name.serialize()} = {self.value.serialize()};"
@staticmethod
- def diff(left: "ProtoOption", right: "ProtoOption") -> Sequence["ProtoOptionDiff"]:
- if left is None and right is not None:
- return [ProtoOptionAdded(right)]
- elif left is not None and right is None:
- return [ProtoOptionRemoved(left)]
- elif left is None and right is None:
+ def diff(
+ before: "ProtoOption", after: "ProtoOption"
+ ) -> Sequence["ProtoOptionDiff"]:
+ if before is None and after is not None:
+ return [ProtoOptionAdded(after)]
+ elif before is not None and after is None:
+ return [ProtoOptionRemoved(before)]
+ elif before is None and after is None:
return []
- elif left.name != right.name:
+ elif before.name != after.name:
return []
- elif left == right:
+ elif before == after:
return []
- return [ProtoOptionValueChanged(left.name, left.value, right.value)]
+ return [ProtoOptionValueChanged(before.name, before.value, after.value)]
@staticmethod
def diff_sets(
- left: Sequence["ProtoOption"], right: Sequence["ProtoOption"]
+ before: Sequence["ProtoOption"], after: Sequence["ProtoOption"]
) -> list["ProtoOptionDiff"]:
diffs: list[ProtoOptionDiff] = []
- left_names = set(o.name.identifier for o in left)
- right_names = set(o.name.identifier for o in right)
- for name in left_names - right_names:
+ before_names = set(o.name.identifier for o in before)
+ after_names = set(o.name.identifier for o in after)
+ for name in before_names - after_names:
diffs.append(
- ProtoOptionAdded(next(i for i in left if i.name.identifier == name))
+ ProtoOptionRemoved(next(i for i in before if i.name.identifier == name))
)
- for name in right_names - left_names:
+ for name in after_names - before_names:
diffs.append(
- ProtoOptionRemoved(next(i for i in right if i.name.identifier == name))
+ ProtoOptionAdded(next(i for i in after if i.name.identifier == name))
)
- for name in left_names & right_names:
- left_option = next(i for i in left if i.name.identifier == name)
- right_option = next(i for i in right if i.name.identifier == name)
- diffs.extend(ProtoOption.diff(left_option, right_option))
+ for name in before_names & after_names:
+ before_option = next(i for i in before if i.name.identifier == name)
+ after_option = next(i for i in after if i.name.identifier == name)
+ diffs.extend(ProtoOption.diff(before_option, after_option))
return diffs
@@ -165,41 +167,41 @@ class ProtoOptionDiff(ProtoNodeDiff):
class ProtoOptionValueChanged(ProtoOptionDiff):
def __init__(
- self, name: ProtoIdentifier, left: ProtoConstant, right: ProtoConstant
+ self, name: ProtoIdentifier, before: ProtoConstant, after: ProtoConstant
):
self.name = name
- self.left = left
- self.right = right
+ self.before = before
+ self.after = after
def __eq__(self, other: object) -> bool:
return (
isinstance(other, ProtoOptionValueChanged)
and self.name == other.name
- and self.left == other.left
- and self.right == other.right
+ and self.before == other.before
+ and self.after == other.after
)
def __str__(self) -> str:
- return f""
+ return f""
class ProtoOptionAdded(ProtoOptionDiff):
- def __init__(self, left: ProtoOption):
- self.left = left
+ def __init__(self, before: ProtoOption):
+ self.before = before
def __eq__(self, other: object) -> bool:
- return isinstance(other, ProtoOptionAdded) and self.left == other.left
+ return isinstance(other, ProtoOptionAdded) and self.before == other.before
def __str__(self) -> str:
- return f""
+ return f""
class ProtoOptionRemoved(ProtoOptionDiff):
- def __init__(self, right: ProtoOption):
- self.right = right
+ def __init__(self, after: ProtoOption):
+ self.after = after
def __eq__(self, other: object) -> bool:
- return isinstance(other, ProtoOptionRemoved) and self.right == other.right
+ return isinstance(other, ProtoOptionRemoved) and self.after == other.after
def __str__(self) -> str:
- return f""
+ return f""
diff --git a/src/proto_package.py b/src/proto_package.py
index d6d714a..f460d30 100644
--- a/src/proto_package.py
+++ b/src/proto_package.py
@@ -54,43 +54,43 @@ def serialize(self) -> str:
@staticmethod
def diff(
- left: Optional["ProtoPackage"], right: Optional["ProtoPackage"]
+ before: Optional["ProtoPackage"], after: Optional["ProtoPackage"]
) -> list["ProtoNodeDiff"]:
- if left == right:
+ if before == after:
return []
- elif left is not None and right is None:
- return [ProtoPackageAdded(left)]
- elif left is None and right is not None:
- return [ProtoPackageRemoved(right)]
+ elif before is not None and after is None:
+ return [ProtoPackageRemoved(before)]
+ elif before is None and after is not None:
+ return [ProtoPackageAdded(after)]
- assert left is not None and right is not None
- return [ProtoPackageChanged(left, right)]
+ assert before is not None and after is not None
+ return [ProtoPackageChanged(before, after)]
class ProtoPackageChanged(ProtoNodeDiff):
- def __init__(self, left: ProtoPackage, right: ProtoPackage):
- self.left = left
- self.right = right
+ def __init__(self, before: ProtoPackage, after: ProtoPackage):
+ self.before = before
+ self.after = after
def __eq__(self, other: object) -> bool:
return (
isinstance(other, ProtoPackageChanged)
- and self.left == other.left
- and self.right == other.right
+ and self.before == other.before
+ and self.after == other.after
)
class ProtoPackageAdded(ProtoNodeDiff):
- def __init__(self, left: ProtoPackage):
- self.left = left
+ def __init__(self, after: ProtoPackage):
+ self.after = after
def __eq__(self, other: object) -> bool:
- return isinstance(other, ProtoPackageAdded) and self.left == other.left
+ return isinstance(other, ProtoPackageAdded) and self.after == other.after
class ProtoPackageRemoved(ProtoNodeDiff):
- def __init__(self, right: ProtoPackage):
- self.right = right
+ def __init__(self, before: ProtoPackage):
+ self.before = before
def __eq__(self, other: object) -> bool:
- return isinstance(other, ProtoPackageRemoved) and self.right == other.right
+ return isinstance(other, ProtoPackageRemoved) and self.before == other.before
diff --git a/src/proto_syntax.py b/src/proto_syntax.py
index 3e2220c..13bc3c4 100644
--- a/src/proto_syntax.py
+++ b/src/proto_syntax.py
@@ -63,20 +63,20 @@ def serialize(self) -> str:
return f"syntax = {self.syntax.serialize()};"
@staticmethod
- def diff(left: "ProtoSyntax", right: "ProtoSyntax") -> list["ProtoNodeDiff"]:
- if left == right:
+ def diff(before: "ProtoSyntax", after: "ProtoSyntax") -> list["ProtoNodeDiff"]:
+ if before == after:
return []
- return [ProtoSyntaxChanged(left, right)]
+ return [ProtoSyntaxChanged(before, after)]
class ProtoSyntaxChanged(ProtoNodeDiff):
- def __init__(self, left: ProtoSyntax, right: ProtoSyntax):
- self.left = left
- self.right = right
+ def __init__(self, before: ProtoSyntax, after: ProtoSyntax):
+ self.before = before
+ self.after = after
def __eq__(self, other: object) -> bool:
return (
isinstance(other, ProtoSyntaxChanged)
- and self.left == other.left
- and self.right == other.right
+ and self.before == other.before
+ and self.after == other.after
)
diff --git a/src/util/compatibility_checker.py b/src/util/compatibility_checker.py
index beb2199..45b16f5 100644
--- a/src/util/compatibility_checker.py
+++ b/src/util/compatibility_checker.py
@@ -12,8 +12,8 @@
class CompatibilityChecker:
allowed_diff_types: list[Type[ProtoNodeDiff]]
- def check_compatibility(self, left: ProtoFile, right: ProtoFile):
- for diff in left.diff(right):
+ def check_compatibility(self, before: ProtoFile, after: ProtoFile):
+ for diff in before.diff(after):
if diff.__class__ in self.allowed_diff_types:
continue
yield diff
@@ -21,13 +21,13 @@ def check_compatibility(self, left: ProtoFile, right: ProtoFile):
def main() -> int:
with open(sys.argv[1], "r") as proto_file:
- left = Parser.loads(proto_file.read())
+ before = Parser.loads(proto_file.read())
with open(sys.argv[2], "r") as proto_file:
- right = Parser.loads(proto_file.read())
+ after = Parser.loads(proto_file.read())
violations = list(
- CompatibilityChecker([ProtoMessageAdded]).check_compatibility(left, right)
+ CompatibilityChecker([ProtoMessageAdded]).check_compatibility(before, after)
)
if violations:
print(f"Violations: {violations}")
diff --git a/test/proto_enum_test.py b/test/proto_enum_test.py
index 1efafc7..095bad5 100644
--- a/test/proto_enum_test.py
+++ b/test/proto_enum_test.py
@@ -9,9 +9,10 @@
ProtoEnumAdded,
ProtoEnumRemoved,
ProtoEnumValue,
+ ProtoEnumValueAdded,
ProtoEnumValueNameChanged,
ProtoEnumValueOption,
- ProtoEnumValueValueChanged,
+ ProtoEnumValueRemoved,
)
from src.proto_identifier import ProtoIdentifier
from src.proto_int import ProtoInt, ProtoIntSign
@@ -413,14 +414,14 @@ def test_diff_different_enum_value_name_returns_enum_diff(self):
],
)
self.assertEqual(
- ProtoEnum.diff(pe1, pe2),
[
ProtoEnumValueNameChanged(
pe1,
- pe2.nodes[0],
- ProtoIdentifier(None, "ME_UNKNOWN"),
+ pe1.nodes[0],
+ ProtoIdentifier(None, "ME_KNOWN"),
)
],
+ ProtoEnum.diff(pe1, pe2),
)
def test_diff_different_enum_value_value_returns_enum_diff(self):
@@ -450,14 +451,20 @@ def test_diff_different_enum_value_value_returns_enum_diff(self):
diff = ProtoEnum.diff(pe1, pe2)
self.assertIn(
- ProtoEnumValueValueChanged(
+ ProtoEnumValueRemoved(
+ pe1,
+ pe1.values[0],
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoEnumValueAdded(
pe1,
pe2.values[0],
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
diff,
)
- self.assertEqual(1, len(diff))
+ self.assertEqual(2, len(diff))
def test_diff_enum_added(self):
pe1 = None
@@ -999,11 +1006,11 @@ def test_diff_sets_overlap(self):
ProtoEnumRemoved(
ProtoEnum(
None,
- ProtoIdentifier(None, "FooEnum2"),
+ ProtoIdentifier(None, "FooEnum"),
[
ProtoEnumValue(
None,
- ProtoIdentifier(None, "FE_UNKNOWN2"),
+ ProtoIdentifier(None, "FE_UNKNOWN"),
ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
@@ -1016,11 +1023,11 @@ def test_diff_sets_overlap(self):
ProtoEnumRemoved(
ProtoEnum(
None,
- ProtoIdentifier(None, "TagEnum2"),
+ ProtoIdentifier(None, "TagEnum"),
[
ProtoEnumValue(
None,
- ProtoIdentifier(None, "TE_UNKNOWN2"),
+ ProtoIdentifier(None, "TE_UNKNOWN"),
ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
@@ -1032,11 +1039,11 @@ def test_diff_sets_overlap(self):
ProtoEnumAdded(
ProtoEnum(
None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier(None, "FooEnum2"),
[
ProtoEnumValue(
None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
+ ProtoIdentifier(None, "FE_UNKNOWN2"),
ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
@@ -1048,11 +1055,11 @@ def test_diff_sets_overlap(self):
ProtoEnumAdded(
ProtoEnum(
None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier(None, "TagEnum2"),
[
ProtoEnumValue(
None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
+ ProtoIdentifier(None, "TE_UNKNOWN2"),
ProtoInt(None, 0, ProtoIntSign.POSITIVE),
)
],
@@ -1075,10 +1082,10 @@ def test_diff_sets_overlap(self):
),
ProtoEnumValue(
None,
- ProtoIdentifier(None, "BE_UNKNOWN2"),
+ ProtoIdentifier(None, "BE_UNKNOWN"),
ProtoInt(None, 0, ProtoIntSign.POSITIVE),
),
- ProtoIdentifier(None, "BE_UNKNOWN"),
+ ProtoIdentifier(None, "BE_UNKNOWN2"),
),
diff,
)
diff --git a/test/proto_message_field_test.py b/test/proto_message_field_test.py
index eb64ca3..513e1f8 100644
--- a/test/proto_message_field_test.py
+++ b/test/proto_message_field_test.py
@@ -6,7 +6,13 @@
ProtoIdentifier,
)
from src.proto_int import ProtoInt, ProtoIntSign
-from src.proto_message_field import ProtoMessageField, ProtoMessageFieldTypesEnum
+from src.proto_message_field import (
+ ProtoMessageField,
+ ProtoMessageFieldAdded,
+ ProtoMessageFieldNameChanged,
+ ProtoMessageFieldRemoved,
+ ProtoMessageFieldTypesEnum,
+)
class MessageFieldTest(unittest.TestCase):
@@ -73,7 +79,7 @@ def test_message_field_starts_with_underscore(self):
parsed_double_undescored_field.node,
ProtoMessageField(
None,
- ProtoMessageFieldTypesEnum.STRING,
+ ProtoMessageFieldTypesEnum.BOOL,
ProtoIdentifier(None, "__test_field"),
ProtoInt(None, 1, ProtoIntSign.POSITIVE),
),
@@ -127,3 +133,270 @@ def test_field_starts_with_period(self):
ProtoEnumOrMessageIdentifier(None, ".google.proto.FooType"),
),
)
+
+ def test_diff_same_field_returns_empty(self):
+ pmf1 = ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "my_message_field"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ )
+ pmf2 = ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "my_message_field"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ )
+ self.assertEqual(ProtoMessageField.diff(None, pmf1, pmf2), [])
+
+ def test_diff_different_field_name_same_number_returns_field_diff(self):
+ pmf1 = ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ )
+ pmf2 = ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "bar"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ )
+ self.assertEqual(
+ [
+ ProtoMessageFieldNameChanged(
+ None,
+ pmf1,
+ pmf2.name,
+ )
+ ],
+ ProtoMessageField.diff(None, pmf1, pmf2),
+ )
+
+ def test_diff_field_removed(self):
+ pmf1 = ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ )
+ pmf2 = None
+ self.assertEqual(
+ [
+ ProtoMessageFieldRemoved(None, pmf1),
+ ],
+ ProtoMessageField.diff(None, pmf1, pmf2),
+ )
+
+ def test_diff_sets_empty_returns_empty(self):
+ set1 = []
+ set2 = []
+ self.assertEqual(ProtoMessageField.diff_sets(None, set1, set2), [])
+
+ def test_diff_sets_no_change(self):
+ set1 = [
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "bar"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "baz"),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ),
+ ]
+ self.assertEqual([], ProtoMessageField.diff_sets(None, set1, set1))
+
+ def test_diff_sets_all_removed(self):
+ set1 = []
+ set2 = [
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "bar"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "baz"),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ),
+ ]
+ diff = ProtoMessageField.diff_sets(None, set1, set2)
+
+ for pmf in set2:
+ self.assertIn(
+ ProtoMessageFieldRemoved(None, pmf),
+ diff,
+ )
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_all_added(self):
+ set1 = [
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "bar"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "baz"),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ),
+ ]
+ set2 = []
+ diff = ProtoMessageField.diff_sets(None, set1, set2)
+
+ for pmf in set1:
+ self.assertIn(
+ ProtoMessageFieldAdded(None, pmf),
+ diff,
+ )
+
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_mutually_exclusive(self):
+ set1 = [
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "bar"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "baz"),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ),
+ ]
+ set2 = [
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "foo2"),
+ ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "bar2"),
+ ProtoInt(None, 5, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "baz2"),
+ ProtoInt(None, 6, ProtoIntSign.POSITIVE),
+ ),
+ ]
+
+ diff = ProtoMessageField.diff_sets(None, set1, set2)
+
+ for pmf in set1:
+ self.assertIn(
+ ProtoMessageFieldAdded(None, pmf),
+ diff,
+ )
+
+ for pmf in set2:
+ self.assertIn(
+ ProtoMessageFieldRemoved(None, pmf),
+ diff,
+ )
+
+ self.assertEqual(6, len(diff))
+
+ def test_diff_sets_overlap(self):
+ set1 = [
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "foo"),
+ ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "bar"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "baz"),
+ ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ),
+ ]
+ set2 = [
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "foo2"),
+ ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "bar"),
+ ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ None,
+ ProtoMessageFieldTypesEnum.FLOAT,
+ ProtoIdentifier(None, "baz2"),
+ ProtoInt(None, 6, ProtoIntSign.POSITIVE),
+ ),
+ ]
+
+ diff = ProtoMessageField.diff_sets(None, set1, set2)
+
+ self.assertIn(
+ ProtoMessageFieldRemoved(None, set1[0]),
+ diff,
+ )
+
+ self.assertIn(
+ ProtoMessageFieldRemoved(None, set1[2]),
+ diff,
+ )
+ self.assertIn(
+ ProtoMessageFieldAdded(None, set2[0]),
+ diff,
+ )
+ self.assertIn(
+ ProtoMessageFieldAdded(None, set2[2]),
+ diff,
+ )
+
+ self.assertEqual(4, len(diff))
diff --git a/test/proto_message_test.py b/test/proto_message_test.py
index 2a62886..9e0f684 100644
--- a/test/proto_message_test.py
+++ b/test/proto_message_test.py
@@ -941,12 +941,12 @@ def test_diff_sets_no_change_returns_empty(self):
self.assertEqual(ProtoMessage.diff_sets(set1, set1), [])
def test_diff_sets_all_removed(self):
- set1 = []
- set2 = [
+ set1 = [
ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
]
+ set2 = []
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
ProtoMessageRemoved(
@@ -969,12 +969,12 @@ def test_diff_sets_all_removed(self):
self.assertEqual(3, len(diff))
def test_diff_sets_all_added(self):
- set1 = [
+ set1 = []
+ set2 = [
ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
]
- set2 = []
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
@@ -1011,37 +1011,37 @@ def test_diff_sets_mutually_exclusive(self):
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), [])
),
diff,
)
self.assertIn(
ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage2"), [])
),
diff,
)
self.assertIn(
ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), [])
),
diff,
)
self.assertIn(
ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
),
diff,
)
self.assertIn(
ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage2"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), [])
),
diff,
)
self.assertIn(
ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
),
diff,
)
@@ -1062,25 +1062,25 @@ def test_diff_sets_overlap(self):
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), [])
),
diff,
)
self.assertIn(
ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), [])
),
diff,
)
self.assertIn(
ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
),
diff,
)
self.assertIn(
ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), [])
+ ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
),
diff,
)
diff --git a/test/proto_option_test.py b/test/proto_option_test.py
index b1f4ff1..b4f52fc 100644
--- a/test/proto_option_test.py
+++ b/test/proto_option_test.py
@@ -328,8 +328,7 @@ def test_diff_sets_no_change(self):
self.assertEqual(ProtoOption.diff_sets(set1, set1), [])
def test_diff_sets_all_removed(self):
- set1 = []
- set2 = [
+ set1 = [
ProtoOption(
None,
ProtoIdentifier(None, "some.custom.option"),
@@ -346,6 +345,7 @@ def test_diff_sets_all_removed(self):
ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
+ set2 = []
diff = ProtoOption.diff_sets(set1, set2)
self.assertIn(
@@ -381,7 +381,8 @@ def test_diff_sets_all_removed(self):
self.assertEqual(3, len(diff))
def test_diff_sets_all_added(self):
- set1 = [
+ set1 = []
+ set2 = [
ProtoOption(
None,
ProtoIdentifier(None, "some.custom.option"),
@@ -398,7 +399,6 @@ def test_diff_sets_all_added(self):
ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
- set2 = []
diff = ProtoOption.diff_sets(set1, set2)
self.assertIn(
@@ -437,34 +437,34 @@ def test_diff_sets_mutually_exclusive(self):
set1 = [
ProtoOption(
None,
- ProtoIdentifier(None, "some.custom.option.but.not.prior"),
+ ProtoIdentifier(None, "some.custom.option"),
ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
None,
- ProtoIdentifier(None, "ruby_package"),
+ ProtoIdentifier(None, "java_package"),
ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
ProtoOption(
None,
- ProtoIdentifier(None, "other.option.but.stil.not.prior"),
+ ProtoIdentifier(None, "other.option"),
ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
set2 = [
ProtoOption(
None,
- ProtoIdentifier(None, "some.custom.option"),
+ ProtoIdentifier(None, "some.custom.option.but.not.prior"),
ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
None,
- ProtoIdentifier(None, "java_package"),
+ ProtoIdentifier(None, "ruby_package"),
ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
ProtoOption(
None,
- ProtoIdentifier(None, "other.option"),
+ ProtoIdentifier(None, "other.option.but.stil.not.prior"),
ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
@@ -542,34 +542,34 @@ def test_diff_sets_overlap(self):
set1 = [
ProtoOption(
None,
- ProtoIdentifier(None, "some.custom.option.but.not.prior"),
+ ProtoIdentifier(None, "some.custom.option"),
ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
None,
ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.bat")),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
),
ProtoOption(
None,
- ProtoIdentifier(None, "other.option.but.stil.not.prior"),
+ ProtoIdentifier(None, "other.option"),
ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
set2 = [
ProtoOption(
None,
- ProtoIdentifier(None, "some.custom.option"),
+ ProtoIdentifier(None, "some.custom.option.but.not.prior"),
ProtoConstant(None, ProtoStringLiteral(None, "some value")),
),
ProtoOption(
None,
ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.bat")),
),
ProtoOption(
None,
- ProtoIdentifier(None, "other.option"),
+ ProtoIdentifier(None, "other.option.but.stil.not.prior"),
ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
),
]
@@ -620,8 +620,8 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoOptionValueChanged(
ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.bat")),
ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.bat")),
),
diff,
)
diff --git a/test/proto_package_test.py b/test/proto_package_test.py
index 20289a9..611dd37 100644
--- a/test/proto_package_test.py
+++ b/test/proto_package_test.py
@@ -82,23 +82,23 @@ def test_diff_different_package_returns_package_diff(self):
)
def test_diff_package_added(self):
- pp1 = ProtoPackage(None, "my.new.package")
- pp2 = None
+ pp1 = None
+ pp2 = ProtoPackage(None, "my.new.package")
self.assertEqual(
- ProtoPackage.diff(pp1, pp2),
[
ProtoPackageAdded(ProtoPackage(None, "my.new.package")),
],
+ ProtoPackage.diff(pp1, pp2),
)
def test_diff_package_removed(self):
- pp1 = None
- pp2 = ProtoPackage(None, "my.old.package")
+ pp1 = ProtoPackage(None, "my.old.package")
+ pp2 = None
self.assertEqual(
- ProtoPackage.diff(pp1, pp2),
[
ProtoPackageRemoved(ProtoPackage(None, "my.old.package")),
],
+ ProtoPackage.diff(pp1, pp2),
)
diff --git a/test/util/compatibility_checker_binary_test.sh b/test/util/compatibility_checker_binary_test.sh
index da18716..63cd61f 100755
--- a/test/util/compatibility_checker_binary_test.sh
+++ b/test/util/compatibility_checker_binary_test.sh
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
set -euxo pipefail
-./src/util/compatibility_checker_binary ./test/resources/single_message.proto ./test/resources/empty.proto
+./src/util/compatibility_checker_binary ./test/resources/empty.proto ./test/resources/single_message.proto
From ec5bc9d109fffa0c985874c055d2bf22e7c4ba7e Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Mon, 20 Feb 2023 19:01:41 -0500
Subject: [PATCH 16/35] Fix target names in readme (#73)
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index b6e911f..5e98825 100644
--- a/README.md
+++ b/README.md
@@ -8,13 +8,13 @@ This is a Python-based protobuf parser. It is intended to serve as a reference i
Right now, the primary way to use this as a library in your Bazelified Python code.
-Mount this repo in your Bazel workspace, then add `@py_proto//src:parser` as a dependency:
+Mount this repo in your Bazel workspace, then add `@py_proto//src/util:parser` as a dependency:
```
py_library(
name = "your_python_code",
# ...
deps = [
- "@py_proto//src:parser",
+ "@py_proto//src/util:parser",
]
)
```
From b04dd94014130f66a6d894d766ae0f33a7bf3f5d Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Mon, 20 Feb 2023 19:08:47 -0500
Subject: [PATCH 17/35] Actually run two test suites that were accidentally off
(#74)
---
test/proto_map_test.py | 4 ++++
test/proto_message_field_test.py | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/test/proto_map_test.py b/test/proto_map_test.py
index f45d214..b67c424 100644
--- a/test/proto_map_test.py
+++ b/test/proto_map_test.py
@@ -98,3 +98,7 @@ def test_map_message_value(self):
[],
),
)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/test/proto_message_field_test.py b/test/proto_message_field_test.py
index 513e1f8..26c82e6 100644
--- a/test/proto_message_field_test.py
+++ b/test/proto_message_field_test.py
@@ -400,3 +400,7 @@ def test_diff_sets_overlap(self):
)
self.assertEqual(4, len(diff))
+
+
+if __name__ == "__main__":
+ unittest.main()
From 062c2c98783a9e69ec47db55169725967f0770e7 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Mon, 20 Feb 2023 22:32:41 -0500
Subject: [PATCH 18/35] Simplify API, by making parent an optional argument in
ProtoNode (#75)
---
src/proto_bool.py | 10 +-
src/proto_comment.py | 16 +-
src/proto_constant.py | 38 +--
src/proto_enum.py | 52 +--
src/proto_extend.py | 15 +-
src/proto_extensions.py | 17 +-
src/proto_float.py | 17 +-
src/proto_identifier.py | 30 +-
src/proto_import.py | 11 +-
src/proto_int.py | 12 +-
src/proto_map.py | 29 +-
src/proto_message.py | 15 +-
src/proto_message_field.py | 37 +-
src/proto_node.py | 6 +-
src/proto_oneof.py | 15 +-
src/proto_option.py | 30 +-
src/proto_package.py | 10 +-
src/proto_range.py | 19 +-
src/proto_reserved.py | 16 +-
src/proto_service.py | 55 ++-
src/proto_string_literal.py | 8 +-
src/proto_syntax.py | 12 +-
src/util/parser.py | 6 +-
test/proto_bool_test.py | 20 +-
test/proto_comment_test.py | 28 +-
test/proto_constant_test.py | 164 ++++-----
test/proto_enum_test.py | 545 +++++++++++-------------------
test/proto_extend_test.py | 22 +-
test/proto_extensions_test.py | 12 +-
test/proto_float_test.py | 74 ++--
test/proto_identifier_test.py | 92 +++--
test/proto_import_test.py | 66 ++--
test/proto_int_test.py | 24 +-
test/proto_map_test.py | 48 +--
test/proto_message_field_test.py | 190 +++++------
test/proto_message_test.py | 523 ++++++++++------------------
test/proto_option_test.py | 383 +++++++++------------
test/proto_package_test.py | 54 ++-
test/proto_range_test.py | 32 +-
test/proto_reserved_test.py | 18 +-
test/proto_service_test.py | 174 ++++------
test/proto_string_literal_test.py | 26 +-
test/proto_syntax_test.py | 64 ++--
test/util/parser_test.py | 193 ++++-------
44 files changed, 1365 insertions(+), 1863 deletions(-)
diff --git a/src/proto_bool.py b/src/proto_bool.py
index 879f0ff..d61d5a0 100644
--- a/src/proto_bool.py
+++ b/src/proto_bool.py
@@ -10,8 +10,8 @@ class ParsedProtoBoolNode(ParsedProtoNode):
class ProtoBool(ProtoNode):
- def __init__(self, parent: Optional[ProtoNode], value: bool):
- super().__init__(parent)
+ def __init__(self, value: bool, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.value = value
def __bool__(self) -> bool:
@@ -31,19 +31,19 @@ def normalize(self) -> "ProtoBool":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoBoolNode"]:
if proto_source.startswith("true") and (
len(proto_source) == 4 or proto_source[4] not in ProtoFullIdentifier.ALL
):
return ParsedProtoBoolNode(
- ProtoBool(parent, True), proto_source[4:].strip()
+ ProtoBool(value=True, parent=parent), proto_source[4:].strip()
)
elif proto_source.startswith("false") and (
len(proto_source) == 5 or proto_source[5] not in ProtoFullIdentifier.ALL
):
return ParsedProtoBoolNode(
- ProtoBool(parent, False), proto_source[5:].strip()
+ ProtoBool(value=False, parent=parent), proto_source[5:].strip()
)
return None
diff --git a/src/proto_comment.py b/src/proto_comment.py
index d3d6db7..bf7b3d7 100644
--- a/src/proto_comment.py
+++ b/src/proto_comment.py
@@ -10,8 +10,8 @@ class ParsedProtoCommentNode(ParsedProtoNode):
class ProtoComment(ProtoNode):
- def __init__(self, parent: Optional[ProtoNode], value: str):
- super().__init__(parent)
+ def __init__(self, value: str, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.value = value
def __eq__(self, other) -> bool:
@@ -28,7 +28,7 @@ def normalize(self) -> Optional["ProtoComment"]:
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoCommentNode"]:
return None
@@ -47,7 +47,7 @@ def __str__(self) -> str:
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoSingleLineCommentNode"]:
if not proto_source.startswith("//"):
return None
@@ -57,7 +57,7 @@ def match(
if newline_pos == -1:
newline_pos = len(proto_source)
return ParsedProtoSingleLineCommentNode(
- ProtoSingleLineComment(parent, proto_source[:newline_pos]),
+ ProtoSingleLineComment(value=proto_source[:newline_pos], parent=parent),
proto_source[newline_pos + 1 :],
)
@@ -76,7 +76,7 @@ def __str__(self) -> str:
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoMultiLineCommentNode"]:
if not proto_source.startswith("/*"):
return None
@@ -86,7 +86,9 @@ def match(
if close_comment_pos == -1:
return None
return ParsedProtoMultiLineCommentNode(
- ProtoMultiLineComment(parent, proto_source[:close_comment_pos]),
+ ProtoMultiLineComment(
+ value=proto_source[:close_comment_pos], parent=parent
+ ),
proto_source[close_comment_pos + 2 :],
)
diff --git a/src/proto_constant.py b/src/proto_constant.py
index 10cb623..464d6ae 100644
--- a/src/proto_constant.py
+++ b/src/proto_constant.py
@@ -18,12 +18,8 @@ class ParsedProtoConstantNode(ParsedProtoNode):
class ProtoConstant(ProtoNode):
- def __init__(
- self,
- parent: Optional[ProtoNode],
- value: ProtoConstantTypes,
- ):
- super().__init__(parent)
+ def __init__(self, value: ProtoConstantTypes, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.value = value
self.value.parent = self
@@ -41,11 +37,11 @@ def normalize(self) -> "ProtoConstant":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoConstantNode"]:
- match = ProtoBool.match(None, proto_source)
+ match = ProtoBool.match(proto_source=proto_source)
if match is not None:
- proto_constant = ProtoConstant(parent, match.node)
+ proto_constant = ProtoConstant(value=match.node, parent=parent)
return ParsedProtoConstantNode(
proto_constant,
match.remaining_source.strip(),
@@ -54,11 +50,11 @@ def match(
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("+") or proto_source.startswith("-"):
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- proto_int_match = ProtoInt.match(None, proto_source[1:])
+ proto_int_match = ProtoInt.match(proto_source=proto_source[1:])
else:
- proto_int_match = ProtoInt.match(None, proto_source)
+ proto_int_match = ProtoInt.match(proto_source=proto_source)
if proto_int_match is not None:
- proto_constant = ProtoConstant(parent, proto_int_match.node)
+ proto_constant = ProtoConstant(value=proto_int_match.node, parent=parent)
proto_int_match.node.sign = sign
return ParsedProtoConstantNode(
proto_constant,
@@ -68,28 +64,32 @@ def match(
float_sign = ProtoFloatSign.POSITIVE
if proto_source.startswith("+") or proto_source.startswith("-"):
float_sign = next(x for x in ProtoFloatSign if x.value == proto_source[0])
- float_match = ProtoFloat.match(None, proto_source[1:])
+ float_match = ProtoFloat.match(proto_source=proto_source[1:])
else:
- float_match = ProtoFloat.match(None, proto_source)
+ float_match = ProtoFloat.match(proto_source=proto_source)
if float_match is not None:
- proto_constant = ProtoConstant(parent, float_match.node)
+ proto_constant = ProtoConstant(value=float_match.node, parent=parent)
float_match.node.sign = float_sign
return ParsedProtoConstantNode(
proto_constant,
float_match.remaining_source.strip(),
)
- identifier_match = ProtoFullIdentifier.match(None, proto_source)
+ identifier_match = ProtoFullIdentifier.match(
+ proto_source=proto_source, parent=None
+ )
if identifier_match is not None:
return ParsedProtoConstantNode(
- ProtoConstant(parent, identifier_match.node),
+ ProtoConstant(value=identifier_match.node, parent=parent),
identifier_match.remaining_source.strip(),
)
- string_literal_match = ProtoStringLiteral.match(None, proto_source)
+ string_literal_match = ProtoStringLiteral.match(
+ proto_source=proto_source, parent=None
+ )
if string_literal_match is not None:
return ParsedProtoConstantNode(
- ProtoConstant(parent, string_literal_match.node),
+ ProtoConstant(value=string_literal_match.node, parent=parent),
string_literal_match.remaining_source.strip(),
)
diff --git a/src/proto_enum.py b/src/proto_enum.py
index c1f682c..b427221 100644
--- a/src/proto_enum.py
+++ b/src/proto_enum.py
@@ -23,14 +23,14 @@ def __str__(self) -> str:
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoEnumValueOptionNode"]:
test_source = "option " + proto_source.strip() + ";"
- match = ProtoOption.match(None, test_source)
+ match = ProtoOption.match(proto_source=test_source)
if match is None:
return None
return ParsedProtoEnumValueOptionNode(
- cls(parent, match.node.name, match.node.value),
+ cls(name=match.node.name, value=match.node.value, parent=parent),
match.remaining_source.strip(),
)
@@ -46,12 +46,13 @@ class ParsedProtoEnumValueNode(ParsedProtoNode):
class ProtoEnumValue(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
identifier: ProtoIdentifier,
value: ProtoInt,
options: Optional[list[ProtoEnumValueOption]] = None,
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.identifier = identifier
self.identifier.parent = self
self.value = value
@@ -82,17 +83,17 @@ def __hash__(self) -> int:
def normalize(self) -> "ProtoEnumValue":
return ProtoEnumValue(
- self.parent,
self.identifier,
self.value,
sorted(self.options, key=lambda o: str(o.name)),
+ parent=self.parent,
)
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoEnumValueNode"]:
- match = ProtoIdentifier.match(None, proto_source)
+ match = ProtoIdentifier.match(proto_source=proto_source)
if match is None:
raise ValueError(f"Proto has invalid enum value name: {proto_source}")
@@ -109,9 +110,9 @@ def match(
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("-"):
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- int_match = ProtoInt.match(None, proto_source[1:])
+ int_match = ProtoInt.match(proto_source=proto_source[1:])
else:
- int_match = ProtoInt.match(None, proto_source)
+ int_match = ProtoInt.match(proto_source=proto_source)
if int_match is None:
raise ValueError(
f"Proto has invalid enum value, expecting int: {proto_source}"
@@ -131,7 +132,7 @@ def match(
)
for option_part in proto_source[:end_bracket].strip().split(","):
proto_enum_value_option_match = ProtoEnumValueOption.match(
- None, option_part.strip()
+ proto_source=option_part.strip(), parent=None
)
if proto_enum_value_option_match is None:
raise ValueError(
@@ -141,7 +142,12 @@ def match(
proto_source = proto_source[end_bracket + 1 :].strip()
return ParsedProtoEnumValueNode(
- ProtoEnumValue(parent, enum_value_name, enum_value, options),
+ ProtoEnumValue(
+ identifier=enum_value_name,
+ value=enum_value,
+ options=options,
+ parent=parent,
+ ),
proto_source.strip(),
)
@@ -205,10 +211,8 @@ def diff_sets(
class ProtoEnum(ProtoNode):
- def __init__(
- self, parent: Optional[ProtoNode], name: ProtoIdentifier, nodes: list[ProtoNode]
- ):
- super().__init__(parent)
+ def __init__(self, name: ProtoIdentifier, nodes: list[ProtoNode], *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
self.nodes = nodes
@@ -233,9 +237,9 @@ def normalize(self) -> "ProtoEnum":
lambda n1: not isinstance(n1, ProtoComment), self.nodes
)
return ProtoEnum(
- self.parent,
- self.name,
- sorted(non_comment_nodes, key=lambda n: str(n.normalize())),
+ name=self.name,
+ nodes=sorted(non_comment_nodes, key=lambda n: str(n.normalize())),
+ parent=self.parent,
)
@staticmethod
@@ -249,7 +253,9 @@ def parse_partial_content(partial_enum_content: str) -> ParsedProtoNode:
]
for node_type in supported_types:
try:
- match_result = node_type.match(None, partial_enum_content)
+ match_result = node_type.match(
+ proto_source=partial_enum_content, parent=None
+ )
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial enum content:\n{partial_enum_content}"
@@ -262,13 +268,13 @@ def parse_partial_content(partial_enum_content: str) -> ParsedProtoNode:
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("enum "):
return None
proto_source = proto_source[5:]
- match = ProtoIdentifier.match(None, proto_source)
+ match = ProtoIdentifier.match(proto_source=proto_source)
if match is None:
raise ValueError(f"Proto has invalid enum name: {proto_source}")
@@ -297,7 +303,7 @@ def match(
proto_source = match_result.remaining_source.strip()
return ParsedProtoNode(
- ProtoEnum(parent, enum_name, nodes=parsed_tree), proto_source
+ ProtoEnum(name=enum_name, nodes=parsed_tree, parent=parent), proto_source
)
@property
diff --git a/src/proto_extend.py b/src/proto_extend.py
index 8585fdb..ece3e23 100644
--- a/src/proto_extend.py
+++ b/src/proto_extend.py
@@ -13,11 +13,12 @@
class ProtoExtend(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
name: ProtoEnumOrMessageIdentifier,
nodes: list[ProtoNode],
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
self.nodes = nodes
@@ -38,9 +39,9 @@ def normalize(self) -> "ProtoExtend":
lambda n: not isinstance(n, ProtoComment), self.nodes
)
return ProtoExtend(
- self.parent,
name=self.name,
nodes=sorted(non_comment_nodes, key=lambda f: str(f)),
+ parent=self.parent,
)
@staticmethod
@@ -52,7 +53,7 @@ def parse_partial_content(partial_content: str) -> ParsedProtoNode:
]
for node_type in supported_types:
try:
- match_result = node_type.match(None, partial_content)
+ match_result = node_type.match(partial_content)
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial extend content:\n{partial_content}"
@@ -63,13 +64,13 @@ def parse_partial_content(partial_content: str) -> ParsedProtoNode:
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("extend "):
return None
proto_source = proto_source[7:]
- match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
+ match = ProtoEnumOrMessageIdentifier.match(proto_source)
if match is None:
raise ValueError(f"Proto extend has invalid message name: {proto_source}")
@@ -98,7 +99,7 @@ def match(
proto_source = match_result.remaining_source.strip()
return ParsedProtoNode(
- ProtoExtend(parent, name, nodes=parsed_tree), proto_source
+ ProtoExtend(name=name, nodes=parsed_tree, parent=parent), proto_source
)
def serialize(self) -> str:
diff --git a/src/proto_extensions.py b/src/proto_extensions.py
index c8cf998..39ad012 100644
--- a/src/proto_extensions.py
+++ b/src/proto_extensions.py
@@ -9,10 +9,11 @@
class ProtoExtensions(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
ranges: list[ProtoRange],
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.ranges = ranges
for range in self.ranges:
range.parent = self
@@ -29,13 +30,13 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoExtensions":
# sort the ranges.
return ProtoExtensions(
- self.parent,
- sorted(self.ranges, key=lambda r: int(r.min)),
+ ranges=sorted(self.ranges, key=lambda r: int(r.min)),
+ parent=self.parent,
)
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("extensions "):
return None
@@ -53,13 +54,15 @@ def match(
)
if proto_source[0] == ",":
proto_source = proto_source[1:].strip()
- match = ProtoRange.match(None, proto_source)
+ match = ProtoRange.match(proto_source)
if match is None:
return None
ranges.append(match.node)
proto_source = match.remaining_source
- return ParsedProtoNode(ProtoExtensions(parent, ranges), proto_source.strip())
+ return ParsedProtoNode(
+ ProtoExtensions(ranges=ranges, parent=parent), proto_source.strip()
+ )
def serialize(self) -> str:
serialize_parts = ["extensions", ", ".join(r.serialize() for r in self.ranges)]
diff --git a/src/proto_float.py b/src/proto_float.py
index d86b22d..f1abca1 100644
--- a/src/proto_float.py
+++ b/src/proto_float.py
@@ -22,8 +22,8 @@ class ProtoFloat(ProtoNode):
DECIMAL = DIGITS | set(".")
EXPONENTIAL = set("eE")
- def __init__(self, parent: Optional[ProtoNode], value: float, sign: ProtoFloatSign):
- super().__init__(parent)
+ def __init__(self, value: float, sign: ProtoFloatSign, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.value = value
self.sign = sign
@@ -45,7 +45,7 @@ def normalize(self) -> "ProtoFloat":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoFloatNode"]:
if proto_source.startswith("inf"):
proto_source = proto_source[3:]
@@ -54,7 +54,9 @@ def match(
f"Proto has invalid float, invalid post-inf character: {proto_source}"
)
return ParsedProtoFloatNode(
- ProtoFloat(parent, float("inf"), ProtoFloatSign.POSITIVE),
+ ProtoFloat(
+ value=float("inf"), sign=ProtoFloatSign.POSITIVE, parent=parent
+ ),
proto_source.strip(),
)
@@ -65,7 +67,9 @@ def match(
f"Proto has invalid float, invalid post-nan character: {proto_source}"
)
return ParsedProtoFloatNode(
- ProtoFloat(parent, float("nan"), ProtoFloatSign.POSITIVE),
+ ProtoFloat(
+ value=float("nan"), sign=ProtoFloatSign.POSITIVE, parent=parent
+ ),
proto_source.strip(),
)
@@ -118,7 +122,8 @@ def match(
proto_source = proto_source[i + 1 :]
return ParsedProtoFloatNode(
- ProtoFloat(parent, base, ProtoFloatSign.POSITIVE), proto_source.strip()
+ ProtoFloat(value=base, sign=ProtoFloatSign.POSITIVE, parent=parent),
+ proto_source.strip(),
)
def serialize(self) -> str:
diff --git a/src/proto_identifier.py b/src/proto_identifier.py
index 114c684..dbc93b5 100644
--- a/src/proto_identifier.py
+++ b/src/proto_identifier.py
@@ -23,8 +23,8 @@ class ProtoIdentifier(ProtoNode):
STARTING = ALPHABETICAL | set("_")
ALL = STARTING | set("0123456789_")
- def __init__(self, parent: Optional[ProtoNode], identifier: str):
- super().__init__(parent)
+ def __init__(self, identifier: str, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.identifier = identifier
def __eq__(self, other) -> bool:
@@ -44,7 +44,7 @@ def normalize(self) -> "ProtoIdentifier":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoIdentifierNode"]:
if proto_source[0] not in ProtoIdentifier.STARTING:
return None
@@ -52,9 +52,12 @@ def match(
for i, c in enumerate(proto_source):
if c not in ProtoIdentifier.ALL:
return ParsedProtoIdentifierNode(
- ProtoIdentifier(parent, proto_source[:i]), proto_source[i:]
+ ProtoIdentifier(identifier=proto_source[:i], parent=parent),
+ proto_source[i:],
)
- return ParsedProtoIdentifierNode(ProtoIdentifier(parent, proto_source), "")
+ return ParsedProtoIdentifierNode(
+ ProtoIdentifier(identifier=proto_source, parent=parent), ""
+ )
def serialize(self) -> str:
return self.identifier
@@ -66,7 +69,7 @@ class ProtoFullIdentifier(ProtoIdentifier):
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoFullIdentifierNode"]:
if proto_source[0] not in ProtoFullIdentifier.STARTING:
return None
@@ -82,7 +85,9 @@ def match(
)
identifier_parts.append(proto_source[last_part_start:i])
return ParsedProtoFullIdentifierNode(
- ProtoFullIdentifier(parent, ".".join(identifier_parts)),
+ ProtoFullIdentifier(
+ identifier=".".join(identifier_parts), parent=parent
+ ),
proto_source[i:],
)
elif c == ".":
@@ -96,7 +101,8 @@ def match(
)
identifier_parts.append(proto_source[last_part_start:])
return ParsedProtoFullIdentifierNode(
- ProtoFullIdentifier(parent, ".".join(identifier_parts)), ""
+ ProtoFullIdentifier(identifier=".".join(identifier_parts), parent=parent),
+ "",
)
@@ -106,17 +112,19 @@ class ProtoEnumOrMessageIdentifier(ProtoIdentifier):
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoEnumOrMessageIdentifierNode"]:
if proto_source[0] == ".":
matched_source = proto_source[1:]
else:
matched_source = proto_source
- identifier_match = ProtoFullIdentifier.match(parent, matched_source)
+ identifier_match = ProtoFullIdentifier.match(matched_source, parent=parent)
if identifier_match is not None:
match = ParsedProtoEnumOrMessageIdentifierNode(
- ProtoEnumOrMessageIdentifier(parent, identifier_match.node.identifier),
+ ProtoEnumOrMessageIdentifier(
+ identifier=identifier_match.node.identifier, parent=parent
+ ),
identifier_match.remaining_source,
)
diff --git a/src/proto_import.py b/src/proto_import.py
index 4cda9a3..31a1fb6 100644
--- a/src/proto_import.py
+++ b/src/proto_import.py
@@ -7,12 +7,13 @@
class ProtoImport(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
path: ProtoStringLiteral,
weak: bool = False,
public: bool = False,
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.path = path
self.path.parent = self
self.weak = weak
@@ -43,7 +44,7 @@ def normalize(self) -> "ProtoImport":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("import "):
return None
@@ -61,7 +62,7 @@ def match(
public = True
proto_source = proto_source[7:]
- match = ProtoStringLiteral.match(None, proto_source)
+ match = ProtoStringLiteral.match(proto_source)
if match is None:
raise ValueError(f"Proto has invalid import syntax: {proto_source}")
@@ -71,7 +72,7 @@ def match(
)
return ParsedProtoNode(
- ProtoImport(parent, match.node, weak=weak, public=public),
+ ProtoImport(path=match.node, weak=weak, public=public, parent=parent),
match.remaining_source[1:].strip(),
)
diff --git a/src/proto_int.py b/src/proto_int.py
index 480817f..8bae791 100644
--- a/src/proto_int.py
+++ b/src/proto_int.py
@@ -20,8 +20,8 @@ class ProtoInt(ProtoNode):
DECIMAL = OCTAL | set("89")
HEX = DECIMAL | set("ABCDEFabcdef")
- def __init__(self, parent: Optional[ProtoNode], value: int, sign: ProtoIntSign):
- super().__init__(parent)
+ def __init__(self, value: int, sign: ProtoIntSign, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.value = value
self.sign = sign
@@ -45,7 +45,7 @@ def normalize(self) -> "ProtoInt":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoIntNode"]:
if proto_source[0] not in ProtoInt.DECIMAL:
return None
@@ -67,7 +67,7 @@ def match(
except ValueError:
raise ValueError(f"Proto has invalid hex: {proto_source}")
return ParsedProtoIntNode(
- ProtoInt(parent, value, ProtoIntSign.POSITIVE),
+ ProtoInt(value=value, sign=ProtoIntSign.POSITIVE, parent=parent),
proto_source[i + 1 :].strip(),
)
else:
@@ -83,7 +83,7 @@ def match(
except ValueError:
raise ValueError(f"Proto has invalid octal: {proto_source}")
return ParsedProtoIntNode(
- ProtoInt(parent, value, ProtoIntSign.POSITIVE),
+ ProtoInt(value=value, sign=ProtoIntSign.POSITIVE, parent=parent),
proto_source[i + 1 :].strip(),
)
else:
@@ -100,7 +100,7 @@ def match(
return None
return ParsedProtoIntNode(
- ProtoInt(parent, value, ProtoIntSign.POSITIVE),
+ ProtoInt(value=value, sign=ProtoIntSign.POSITIVE, parent=parent),
proto_source[i + 1 :].strip(),
)
diff --git a/src/proto_map.py b/src/proto_map.py
index 129b46b..20070f9 100644
--- a/src/proto_map.py
+++ b/src/proto_map.py
@@ -28,15 +28,16 @@ class ProtoMapKeyTypesEnum(Enum):
class ProtoMap(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
key_type: ProtoMapKeyTypesEnum,
value_type: ProtoMapValueTypesEnum,
name: ProtoIdentifier,
number: ProtoInt,
enum_or_message_type_name: Optional[ProtoEnumOrMessageIdentifier] = None,
options: Optional[list[ProtoMessageFieldOption]] = None,
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.key_type = key_type
self.value_type = value_type
self.name = name
@@ -82,7 +83,7 @@ def normalize(self) -> "ProtoMap":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if proto_source.startswith("map "):
proto_source = proto_source[4:].strip()
@@ -120,7 +121,7 @@ def match(
enum_or_message_type_name = None
if value_type is None:
# See if this is an enum or message type.
- match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
+ match = ProtoEnumOrMessageIdentifier.match(proto_source)
if match is None:
return None
value_type = ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE
@@ -132,7 +133,7 @@ def match(
proto_source = proto_source[1:].strip()
# Try to match the map field's name.
- identifier_match = ProtoIdentifier.match(None, proto_source)
+ identifier_match = ProtoIdentifier.match(proto_source)
if identifier_match is None:
return None
name = identifier_match.node
@@ -143,7 +144,7 @@ def match(
proto_source = proto_source[1:].strip()
# Try to match the map field number.
- int_match = ProtoInt.match(None, proto_source)
+ int_match = ProtoInt.match(proto_source)
if int_match is None:
return None
number = int_match.node
@@ -160,7 +161,7 @@ def match(
)
for option_part in proto_source[:end_bracket].strip().split(","):
message_field_option_match = ProtoMessageFieldOption.match(
- None, option_part.strip()
+ option_part.strip()
)
if message_field_option_match is None:
raise ValueError(
@@ -176,13 +177,13 @@ def match(
return ParsedProtoNode(
ProtoMap(
- parent,
- key_type,
- value_type,
- name,
- number,
- enum_or_message_type_name,
- options,
+ key_type=key_type,
+ value_type=value_type,
+ name=name,
+ number=number,
+ enum_or_message_type_name=enum_or_message_type_name,
+ options=options,
+ parent=parent,
),
proto_source[1:].strip(),
)
diff --git a/src/proto_message.py b/src/proto_message.py
index 01277a7..5cc85be 100644
--- a/src/proto_message.py
+++ b/src/proto_message.py
@@ -20,11 +20,12 @@
class ProtoMessage(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
name: ProtoIdentifier,
nodes: Sequence[ProtoNode],
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
self.nodes = nodes
@@ -79,9 +80,9 @@ def normalize(self) -> "ProtoMessage":
)
return ProtoMessage(
- parent=self.parent,
name=self.name,
nodes=sorted_nodes_for_normalizing,
+ parent=self.parent,
)
@staticmethod
@@ -101,7 +102,7 @@ def parse_partial_content(partial_message_content: str) -> ParsedProtoNode:
]
for node_type in supported_types:
try:
- match_result = node_type.match(None, partial_message_content)
+ match_result = node_type.match(partial_message_content)
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial message content:\n{partial_message_content}"
@@ -114,13 +115,13 @@ def parse_partial_content(partial_message_content: str) -> ParsedProtoNode:
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("message "):
return None
proto_source = proto_source[8:]
- match = ProtoIdentifier.match(None, proto_source)
+ match = ProtoIdentifier.match(proto_source)
if match is None:
raise ValueError(f"Proto has invalid message name: {proto_source}")
@@ -149,7 +150,7 @@ def match(
proto_source = match_result.remaining_source.strip()
return ParsedProtoNode(
- ProtoMessage(parent, enum_name, nodes=parsed_tree), proto_source
+ ProtoMessage(name=enum_name, nodes=parsed_tree, parent=parent), proto_source
)
@property
diff --git a/src/proto_message_field.py b/src/proto_message_field.py
index aa5c7c2..2c3c749 100644
--- a/src/proto_message_field.py
+++ b/src/proto_message_field.py
@@ -15,9 +15,9 @@ class ParsedProtoMessageFieldOptionNode(ParsedProtoEnumValueOptionNode):
class ProtoMessageFieldOption(ProtoEnumValueOption):
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoMessageFieldOptionNode"]:
- match = super().match(parent, proto_source)
+ match = super().match(proto_source=proto_source, parent=parent)
if match is None:
return None
@@ -54,7 +54,6 @@ class ParsedProtoMessageFieldNode(ParsedProtoNode):
class ProtoMessageField(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
type: ProtoMessageFieldTypesEnum,
name: ProtoIdentifier,
number: ProtoInt,
@@ -62,8 +61,10 @@ def __init__(
optional: bool = False,
enum_or_message_type_name: Optional[ProtoEnumOrMessageIdentifier] = None,
options: Optional[list[ProtoMessageFieldOption]] = None,
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.type = type
self.name = name
self.name.parent = self
@@ -107,7 +108,6 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoMessageField":
return ProtoMessageField(
- parent=self.parent,
type=self.type,
name=self.name,
number=self.number,
@@ -115,11 +115,12 @@ def normalize(self) -> "ProtoMessageField":
optional=self.optional,
enum_or_message_type_name=self.enum_or_message_type_name,
options=sorted(self.options, key=lambda o: str(o.name)),
+ parent=self.parent,
)
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoMessageFieldNode"]:
# First, try to match the optional repeated.
repeated = False
@@ -150,7 +151,7 @@ def match(
enum_or_message_type_name = None
if matched_type is None:
# See if this is an enum or message type.
- match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
+ match = ProtoEnumOrMessageIdentifier.match(proto_source)
if match is None:
return None
matched_type = ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE
@@ -158,7 +159,7 @@ def match(
proto_source = match.remaining_source.strip()
# Match the field name.
- identifier_match = ProtoIdentifier.match(None, proto_source)
+ identifier_match = ProtoIdentifier.match(proto_source)
if identifier_match is None:
return None
name = identifier_match.node
@@ -169,7 +170,7 @@ def match(
proto_source = proto_source[2:].strip()
# Match the field number.
- int_match = ProtoInt.match(None, proto_source)
+ int_match = ProtoInt.match(proto_source)
if int_match is None:
return None
number = int_match.node
@@ -185,7 +186,7 @@ def match(
)
for option_part in proto_source[:end_bracket].strip().split(","):
message_field_option_match = ProtoMessageFieldOption.match(
- None, option_part.strip()
+ option_part.strip()
)
if message_field_option_match is None:
raise ValueError(
@@ -201,14 +202,14 @@ def match(
return ParsedProtoMessageFieldNode(
ProtoMessageField(
- parent,
- matched_type,
- name,
- number,
- repeated,
- optional,
- enum_or_message_type_name,
- options,
+ type=matched_type,
+ name=name,
+ number=number,
+ repeated=repeated,
+ optional=optional,
+ enum_or_message_type_name=enum_or_message_type_name,
+ options=options,
+ parent=parent,
),
proto_source[1:].strip(),
)
diff --git a/src/proto_node.py b/src/proto_node.py
index 8d10bb4..5647cb6 100644
--- a/src/proto_node.py
+++ b/src/proto_node.py
@@ -6,11 +6,13 @@ class ProtoNode(abc.ABC):
@classmethod
@abc.abstractmethod
def match(
- cls, parent: Optional["ProtoNode"], proto_source: str
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
) -> Optional["ParsedProtoNode"]:
raise NotImplementedError
- def __init__(self, parent: Optional["ProtoNode"]):
+ def __init__(self, parent: Optional["ProtoNode"] = None):
self.parent = parent
@abc.abstractmethod
diff --git a/src/proto_oneof.py b/src/proto_oneof.py
index 5780710..5e225ab 100644
--- a/src/proto_oneof.py
+++ b/src/proto_oneof.py
@@ -32,11 +32,12 @@ class ParsedProtoOneOfNode(ParsedProtoNode):
class ProtoOneOf(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
name: ProtoIdentifier,
nodes: Sequence[ProtoOneOfNodeTypes],
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
self.nodes = nodes
@@ -77,9 +78,9 @@ def normalize(self) -> "ProtoOneOf":
) + sorted(fields, key=lambda f: int(f.number))
return ProtoOneOf(
- parent=self.parent,
name=self.name,
nodes=sorted_nodes_for_normalizing,
+ parent=self.parent,
)
@staticmethod
@@ -92,7 +93,7 @@ def parse_partial_content(partial_oneof_content: str) -> ProtoParsedOneOfNodeTyp
]
for node_type in supported_types:
try:
- match_result = node_type.match(None, partial_oneof_content)
+ match_result = node_type.match(partial_oneof_content)
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial oneof content:\n{partial_oneof_content}"
@@ -105,14 +106,14 @@ def parse_partial_content(partial_oneof_content: str) -> ProtoParsedOneOfNodeTyp
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoOneOfNode"]:
if not proto_source.startswith("oneof "):
return None
proto_source = proto_source[6:].strip()
- match = ProtoIdentifier.match(None, proto_source)
+ match = ProtoIdentifier.match(proto_source)
if match is None:
raise ValueError(
f"Proto has invalid syntax, expecting identifier for oneof: {proto_source}"
@@ -143,7 +144,7 @@ def match(
proto_source = match_result.remaining_source.strip()
return ParsedProtoOneOfNode(
- ProtoOneOf(parent, oneof_name, nodes=parsed_tree), proto_source
+ ProtoOneOf(name=oneof_name, nodes=parsed_tree, parent=parent), proto_source
)
@property
diff --git a/src/proto_option.py b/src/proto_option.py
index 4090378..2d07312 100644
--- a/src/proto_option.py
+++ b/src/proto_option.py
@@ -15,10 +15,8 @@ class ParsedProtoOptionNode(ParsedProtoNode):
class ProtoOption(ProtoNode):
- def __init__(
- self, parent: Optional[ProtoNode], name: ProtoIdentifier, value: ProtoConstant
- ):
- super().__init__(parent)
+ def __init__(self, name: ProtoIdentifier, value: ProtoConstant, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
self.value = value
@@ -41,7 +39,7 @@ def normalize(self) -> "ProtoOption":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoOptionNode"]:
if not proto_source.startswith("option "):
return None
@@ -50,10 +48,10 @@ def match(
name_parts = []
if proto_source.startswith("("):
proto_source = proto_source[1:]
- match = ProtoFullIdentifier.match(None, proto_source)
+ match = ProtoFullIdentifier.match(proto_source)
if match is None or not match.remaining_source.startswith(")"):
# This might be a regular identifier.
- identifier_match = ProtoIdentifier.match(None, proto_source)
+ identifier_match = ProtoIdentifier.match(proto_source)
if (
not identifier_match
or not identifier_match.remaining_source.startswith(")")
@@ -62,19 +60,21 @@ def match(
f"Proto has invalid option when expecting ): {proto_source}"
)
name_parts.append(
- ProtoIdentifier(None, f"({identifier_match.node.identifier})")
+ ProtoIdentifier(identifier=f"({identifier_match.node.identifier})")
)
proto_source = identifier_match.remaining_source[1:]
else:
name_parts.append(
- ProtoFullIdentifier(None, f"({match.node.identifier})")
+ ProtoFullIdentifier(identifier=f"({match.node.identifier})")
)
proto_source = match.remaining_source[1:]
while True:
- identifier_match = ProtoEnumOrMessageIdentifier.match(None, proto_source)
+ identifier_match = ProtoEnumOrMessageIdentifier.match(
+ proto_source=proto_source
+ )
if identifier_match is None:
- identifier_match = ProtoIdentifier.match(None, proto_source)
+ identifier_match = ProtoIdentifier.match(proto_source=proto_source)
if identifier_match is None:
break
name_parts.append(identifier_match.node)
@@ -86,7 +86,7 @@ def match(
f"Proto has invalid option when expecting =: {proto_source}"
)
proto_source = proto_source[1:].strip()
- constant_match = ProtoConstant.match(None, proto_source)
+ constant_match = ProtoConstant.match(proto_source)
if constant_match is None:
raise ValueError(
f"Proto has invalid option when expecting constant: {proto_source}"
@@ -101,15 +101,15 @@ def match(
identifier: ProtoFullIdentifier | ProtoIdentifier
if len(name_parts) > 1:
identifier = ProtoFullIdentifier(
- None, "".join(x.identifier for x in name_parts)
+ identifier="".join(x.identifier for x in name_parts)
)
else:
- identifier = ProtoIdentifier(None, name_parts[0].identifier)
+ identifier = ProtoIdentifier(identifier=name_parts[0].identifier)
proto_option = ProtoOption(
- parent,
name=identifier,
value=constant_match.node,
+ parent=parent,
)
identifier.parent = proto_option
constant_match.node.parent = proto_option
diff --git a/src/proto_package.py b/src/proto_package.py
index f460d30..64eb120 100644
--- a/src/proto_package.py
+++ b/src/proto_package.py
@@ -4,8 +4,8 @@
class ProtoPackage(ProtoNode):
- def __init__(self, parent: Optional[ProtoNode], package: str):
- super().__init__(parent)
+ def __init__(self, package: str, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.package = package
def __eq__(self, other) -> bool:
@@ -22,7 +22,7 @@ def normalize(self) -> "ProtoPackage":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("package"):
return None
@@ -47,7 +47,9 @@ def match(
if package.startswith(".") or package.endswith("."):
raise ValueError(f"Proto has invalid package: {package}")
- return ParsedProtoNode(ProtoPackage(parent, package), proto_source.strip())
+ return ParsedProtoNode(
+ ProtoPackage(package=package, parent=parent), proto_source.strip()
+ )
def serialize(self) -> str:
return f"package {self.package};"
diff --git a/src/proto_range.py b/src/proto_range.py
index b55b279..ce035f9 100644
--- a/src/proto_range.py
+++ b/src/proto_range.py
@@ -17,11 +17,12 @@ class ProtoRangeEnum(Enum):
class ProtoRange(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
min: ProtoInt,
max: Optional[ProtoInt | ProtoRangeEnum] = None,
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.min = min
if (
@@ -47,14 +48,14 @@ def normalize(self) -> "ProtoRange":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoRangeNode"]:
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("-") and proto_source != "-":
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- match = ProtoInt.match(None, proto_source[1:])
+ match = ProtoInt.match(proto_source[1:])
else:
- match = ProtoInt.match(None, proto_source)
+ match = ProtoInt.match(proto_source)
if match is None:
return None
@@ -66,7 +67,7 @@ def match(
if proto_source.startswith("to "):
proto_source = proto_source[3:]
if proto_source.startswith("max"):
- proto_range = ProtoRange(parent, min, ProtoRangeEnum.MAX)
+ proto_range = ProtoRange(min=min, max=ProtoRangeEnum.MAX, parent=parent)
min.parent = proto_range
return ParsedProtoRangeNode(
proto_range,
@@ -76,9 +77,9 @@ def match(
sign = ProtoIntSign.POSITIVE
if proto_source.startswith("-"):
sign = next(x for x in ProtoIntSign if x.value == proto_source[0])
- match = ProtoInt.match(None, proto_source[1:])
+ match = ProtoInt.match(proto_source[1:])
else:
- match = ProtoInt.match(None, proto_source)
+ match = ProtoInt.match(proto_source)
if match is None:
raise ValueError(
f"Proto source has invalid range, expecting int for max: {proto_source}"
@@ -87,7 +88,7 @@ def match(
max = match.node
proto_source = match.remaining_source
- proto_range = ProtoRange(parent, min, max)
+ proto_range = ProtoRange(min=min, max=max, parent=parent)
min.parent = proto_range
if isinstance(max, ProtoNode):
max.parent = proto_range
diff --git a/src/proto_reserved.py b/src/proto_reserved.py
index 06b146b..374123c 100644
--- a/src/proto_reserved.py
+++ b/src/proto_reserved.py
@@ -14,14 +14,15 @@ class ProtoReservedFieldQuoteEnum(Enum):
class ProtoReserved(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
ranges: Optional[list[ProtoRange]] = None,
fields: Optional[list[ProtoIdentifier]] = None,
quote_type: Optional[
ProtoReservedFieldQuoteEnum
] = ProtoReservedFieldQuoteEnum.DOUBLE,
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
if (not ranges and not fields) or (ranges and fields):
raise ValueError(
"Exactly one of ranges or fields must be set in a ProtoReserved"
@@ -72,7 +73,7 @@ def min(self) -> str | int:
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("reserved "):
return None
@@ -92,7 +93,7 @@ def match(
)
if proto_source[0] == ",":
proto_source = proto_source[1:].strip()
- range_match = ProtoRange.match(None, proto_source)
+ range_match = ProtoRange.match(proto_source)
if range_match is not None:
ranges.append(range_match.node)
proto_source = range_match.remaining_source
@@ -109,7 +110,7 @@ def match(
)
quote_type = quote_types[0]
proto_source = proto_source[1:]
- match = ProtoIdentifier.match(None, proto_source)
+ match = ProtoIdentifier.match(proto_source)
if match is None:
raise ValueError(
f"Proto source has invalid reserved syntax, expecting field identifier: {proto_source}"
@@ -124,7 +125,10 @@ def match(
proto_source = proto_source[1:].strip()
return ParsedProtoNode(
- ProtoReserved(parent, ranges, fields, quote_type), proto_source.strip()
+ ProtoReserved(
+ ranges=ranges, fields=fields, quote_type=quote_type, parent=parent
+ ),
+ proto_source.strip(),
)
def serialize(self) -> str:
diff --git a/src/proto_service.py b/src/proto_service.py
index 8ca62d4..d408849 100644
--- a/src/proto_service.py
+++ b/src/proto_service.py
@@ -13,15 +13,16 @@
class ProtoServiceRPC(ProtoNode):
def __init__(
self,
- parent: Optional[ProtoNode],
name: ProtoIdentifier,
request_type: ProtoEnumOrMessageIdentifier,
response_type: ProtoEnumOrMessageIdentifier,
request_stream: bool = False,
response_stream: bool = False,
options: Optional[list[ProtoOption]] = None,
+ *args,
+ **kwargs,
):
- super().__init__(parent)
+ super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
self.request_type = request_type
@@ -55,25 +56,25 @@ def __repr__(self) -> str:
def normalize(self) -> "ProtoServiceRPC":
return ProtoServiceRPC(
- parent=self.parent,
name=self.name,
request_type=self.request_type,
response_type=self.response_type,
request_stream=self.request_stream,
response_stream=self.response_stream,
options=sorted(self.options, key=lambda o: str(o.normalize())),
+ parent=self.parent,
)
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("rpc "):
return None
proto_source = proto_source[4:].strip()
# Match the RPC name.
- name_match = ProtoIdentifier.match(None, proto_source)
+ name_match = ProtoIdentifier.match(proto_source)
if name_match is None:
return None
name = name_match.node
@@ -84,9 +85,7 @@ def match(
proto_source = proto_source[1:].strip()
# Try to parse the request type.
- stream_or_request_name_match = ProtoEnumOrMessageIdentifier.match(
- None, proto_source
- )
+ stream_or_request_name_match = ProtoEnumOrMessageIdentifier.match(proto_source)
if stream_or_request_name_match is None:
return None
@@ -97,7 +96,7 @@ def match(
elif stream_or_request_name_match.node.identifier == "stream":
# Try matching the request name.
potential_request_name_match = ProtoEnumOrMessageIdentifier.match(
- None, stream_or_request_name_match.remaining_source.strip()
+ stream_or_request_name_match.remaining_source.strip()
)
if potential_request_name_match is None:
# No further name.
@@ -124,9 +123,7 @@ def match(
proto_source = proto_source[1:].strip()
# Try to parse the response type.
- stream_or_response_name_match = ProtoEnumOrMessageIdentifier.match(
- None, proto_source
- )
+ stream_or_response_name_match = ProtoEnumOrMessageIdentifier.match(proto_source)
if stream_or_response_name_match is None:
return None
@@ -137,7 +134,7 @@ def match(
elif stream_or_response_name_match.node.identifier == "stream":
# Try matching the response name.
potential_response_name_match = ProtoEnumOrMessageIdentifier.match(
- None, stream_or_response_name_match.remaining_source.strip()
+ stream_or_response_name_match.remaining_source.strip()
)
if potential_response_name_match is None:
# No further name.
@@ -169,7 +166,7 @@ def match(
proto_source = proto_source[1:].strip()
break
- option_match = ProtoOption.match(None, proto_source)
+ option_match = ProtoOption.match(proto_source)
if option_match is None:
return None
options.append(option_match.node)
@@ -181,13 +178,13 @@ def match(
return ParsedProtoNode(
ProtoServiceRPC(
- parent,
- name,
- request_name,
- response_name,
- request_stream,
- response_stream,
- options,
+ name=name,
+ request_type=request_name,
+ response_type=response_name,
+ request_stream=request_stream,
+ response_stream=response_stream,
+ options=options,
+ parent=parent,
),
proto_source.strip(),
)
@@ -222,10 +219,8 @@ def serialize(self) -> str:
class ProtoService(ProtoNode):
- def __init__(
- self, parent: Optional[ProtoNode], name: ProtoIdentifier, nodes: list[ProtoNode]
- ):
- super().__init__(parent)
+ def __init__(self, name: ProtoIdentifier, nodes: list[ProtoNode], *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
self.nodes = nodes
@@ -246,9 +241,9 @@ def normalize(self) -> "ProtoService":
lambda n: not isinstance(n, ProtoComment), self.nodes
)
return ProtoService(
- parent=self.parent,
name=self.name,
nodes=sorted(non_comment_nodes, key=lambda n: str(n.normalize())),
+ parent=self.parent,
)
@staticmethod
@@ -261,7 +256,7 @@ def parse_partial_content(partial_service_content: str) -> ParsedProtoNode:
]
for node_type in supported_types:
try:
- match_result = node_type.match(None, partial_service_content)
+ match_result = node_type.match(partial_service_content)
except (ValueError, IndexError, TypeError):
raise ValueError(
f"Could not parse partial service content:\n{partial_service_content}"
@@ -274,13 +269,13 @@ def parse_partial_content(partial_service_content: str) -> ParsedProtoNode:
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoNode"]:
if not proto_source.startswith("service "):
return None
proto_source = proto_source[8:]
- match = ProtoIdentifier.match(None, proto_source)
+ match = ProtoIdentifier.match(proto_source)
if match is None:
raise ValueError(f"Proto has invalid service name: {proto_source}")
@@ -309,7 +304,7 @@ def match(
proto_source = match_result.remaining_source.strip()
return ParsedProtoNode(
- ProtoService(parent, enum_name, nodes=parsed_tree), proto_source
+ ProtoService(name=enum_name, nodes=parsed_tree, parent=parent), proto_source
)
@property
diff --git a/src/proto_string_literal.py b/src/proto_string_literal.py
index 1d98b57..1941cf4 100644
--- a/src/proto_string_literal.py
+++ b/src/proto_string_literal.py
@@ -11,8 +11,8 @@ class ParsedProtoStringLiteralNode(ParsedProtoNode):
class ProtoStringLiteral(ProtoNode):
QUOTES = ['"', "'"]
- def __init__(self, parent: Optional[ProtoNode], val: str, quote: str = QUOTES[0]):
- super().__init__(parent)
+ def __init__(self, val: str, quote: str = QUOTES[0], *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.value = val
self.quote = quote
@@ -33,7 +33,7 @@ def normalize(self) -> "ProtoStringLiteral":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoStringLiteralNode"]:
if not any(proto_source.startswith(c) for c in ProtoStringLiteral.QUOTES):
return None
@@ -46,7 +46,7 @@ def match(
if c == starting_quote and not escaped:
return ParsedProtoStringLiteralNode(
ProtoStringLiteral(
- parent, proto_source[1 : i + 1], quote=starting_quote
+ val=proto_source[1 : i + 1], quote=starting_quote, parent=parent
),
proto_source[i + 2 :].strip(),
)
diff --git a/src/proto_syntax.py b/src/proto_syntax.py
index 13bc3c4..fe301bf 100644
--- a/src/proto_syntax.py
+++ b/src/proto_syntax.py
@@ -16,8 +16,8 @@ class ProtoSyntaxType(Enum):
class ProtoSyntax(ProtoNode):
- def __init__(self, parent: Optional[ProtoNode], syntax: ProtoStringLiteral):
- super().__init__(parent)
+ def __init__(self, syntax: ProtoStringLiteral, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.syntax = syntax
def __eq__(self, other) -> bool:
@@ -37,25 +37,25 @@ def normalize(self) -> "ProtoSyntax":
@classmethod
def match(
- cls, parent: Optional[ProtoNode], proto_source: str
+ cls, proto_source: str, parent: Optional[ProtoNode] = None
) -> Optional["ParsedProtoSyntaxNode"]:
if not proto_source.startswith("syntax = "):
return None
proto_source = proto_source[9:]
- match = ProtoStringLiteral.match(None, proto_source)
+ match = ProtoStringLiteral.match(proto_source)
if match is None:
raise ValueError(f"Proto has invalid syntax syntax: {proto_source}")
if not match.remaining_source.startswith(";"):
raise ValueError(f"Proto has invalid syntax: {proto_source}")
try:
- syntax_type = ProtoSyntaxType[match.node.value.upper()]
+ ProtoSyntaxType[match.node.value.upper()]
except KeyError:
raise ValueError(
f"Proto has unknown syntax type: {match.node.value}, must be one of: {[proto_type.name for proto_type in ProtoSyntaxType]}"
)
return ParsedProtoSyntaxNode(
- ProtoSyntax(parent, match.node),
+ ProtoSyntax(syntax=match.node, parent=parent),
match.remaining_source.strip(),
)
diff --git a/src/util/parser.py b/src/util/parser.py
index 62a4723..75b9de9 100644
--- a/src/util/parser.py
+++ b/src/util/parser.py
@@ -38,7 +38,7 @@ def parse_partial_content(partial_proto_content: str) -> ParsedProtoNode:
]
for node_type in node_types:
try:
- match_result = node_type.match(None, partial_proto_content)
+ match_result = node_type.match(partial_proto_content)
except (ValueError, IndexError, TypeError):
raise ParseError(
f"Could not parse proto content:\n{partial_proto_content}"
@@ -56,7 +56,7 @@ def parse_syntax_and_preceding_comments(
while True:
for node_type in [ProtoSingleLineComment, ProtoMultiLineComment]:
try:
- match_result = node_type.match(None, proto_content)
+ match_result = node_type.match(proto_content)
except (ValueError, IndexError, TypeError):
raise ParseError(f"Could not parse proto content:\n{proto_content}")
if match_result is not None:
@@ -68,7 +68,7 @@ def parse_syntax_and_preceding_comments(
# Next, parse syntax.
try:
- syntax_match = ProtoSyntax.match(None, proto_content.strip())
+ syntax_match = ProtoSyntax.match(proto_content.strip())
except (ValueError, IndexError, TypeError):
raise ParseError(f"Proto doesn't have parseable syntax:\n{proto_content}")
if syntax_match is None:
diff --git a/test/proto_bool_test.py b/test/proto_bool_test.py
index 7611d75..cc3a035 100644
--- a/test/proto_bool_test.py
+++ b/test/proto_bool_test.py
@@ -5,18 +5,18 @@
class BoolTest(unittest.TestCase):
def test_true(self):
- self.assertEqual(ProtoBool.match(None, "true").node.value, True)
- self.assertIsNone(ProtoBool.match(None, "True"))
- self.assertIsNone(ProtoBool.match(None, "truee"))
- self.assertIsNone(ProtoBool.match(None, "true_true"))
- self.assertIsNone(ProtoBool.match(None, "true.false"))
+ self.assertEqual(ProtoBool.match("true").node.value, True)
+ self.assertIsNone(ProtoBool.match("True"))
+ self.assertIsNone(ProtoBool.match("truee"))
+ self.assertIsNone(ProtoBool.match("true_true"))
+ self.assertIsNone(ProtoBool.match("true.false"))
def test_false(self):
- self.assertEqual(ProtoBool.match(None, "false").node.value, False)
- self.assertIsNone(ProtoBool.match(None, "False"))
- self.assertIsNone(ProtoBool.match(None, "falsee"))
- self.assertIsNone(ProtoBool.match(None, "false_false"))
- self.assertIsNone(ProtoBool.match(None, "false.true"))
+ self.assertEqual(ProtoBool.match("false").node.value, False)
+ self.assertIsNone(ProtoBool.match("False"))
+ self.assertIsNone(ProtoBool.match("falsee"))
+ self.assertIsNone(ProtoBool.match("false_false"))
+ self.assertIsNone(ProtoBool.match("false.true"))
if __name__ == "__main__":
diff --git a/test/proto_comment_test.py b/test/proto_comment_test.py
index 5d3a705..95a37e9 100644
--- a/test/proto_comment_test.py
+++ b/test/proto_comment_test.py
@@ -5,46 +5,42 @@
class ProtoSingleLineCommentTest(unittest.TestCase):
def test_matches_normal_comment(self):
- node = ProtoSingleLineComment.match(
- None, "// hello there, this is a comment"
- ).node
+ node = ProtoSingleLineComment.match("// hello there, this is a comment").node
self.assertEqual(node.value, " hello there, this is a comment")
self.assertEqual(node.serialize(), "// hello there, this is a comment")
self.assertIsNone(node.normalize())
def test_matches_without_space(self):
- node = ProtoSingleLineComment.match(None, "//comment without space").node
+ node = ProtoSingleLineComment.match("//comment without space").node
self.assertEqual(node.value, "comment without space")
self.assertEqual(node.serialize(), "//comment without space")
self.assertIsNone(node.normalize())
def test_does_not_match_multiple_lines(self):
- node = ProtoSingleLineComment.match(None, "//line one\nbut not this").node
+ node = ProtoSingleLineComment.match("//line one\nbut not this").node
self.assertEqual(node.value, "line one")
self.assertEqual(node.serialize(), "//line one")
self.assertIsNone(node.normalize())
def test_does_not_match_single_slash(self):
self.assertIsNone(
- ProtoSingleLineComment.match(None, "/hello there, this is a comment")
+ ProtoSingleLineComment.match("/hello there, this is a comment")
)
self.assertIsNone(
- ProtoSingleLineComment.match(None, "/ /hello there, this is a comment")
+ ProtoSingleLineComment.match("/ /hello there, this is a comment")
)
class ProtoMultiLineCommentTest(unittest.TestCase):
def test_matches_single_line_comment(self):
- node = ProtoMultiLineComment.match(
- None, "/* hello there, this is a comment */"
- ).node
+ node = ProtoMultiLineComment.match("/* hello there, this is a comment */").node
self.assertEqual(node.value, " hello there, this is a comment ")
self.assertEqual(node.serialize(), "/* hello there, this is a comment */")
self.assertIsNone(node.normalize())
def test_matches_multi_line_comment(self):
node = ProtoMultiLineComment.match(
- None, "/* hello there,\nthis is a \nmulti-line comment */"
+ "/* hello there,\nthis is a \nmulti-line comment */"
).node
self.assertEqual(node.value, " hello there,\nthis is a \nmulti-line comment ")
self.assertEqual(
@@ -55,25 +51,25 @@ def test_matches_multi_line_comment(self):
def test_does_not_match_unclosed_comment(self):
self.assertIsNone(
ProtoMultiLineComment.match(
- None, "/* hello there, this\n /is an unclosed\n*multiple-line comment/"
+ "/* hello there, this\n /is an unclosed\n*multiple-line comment/"
)
)
def test_matches_without_space(self):
- node = ProtoMultiLineComment.match(None, "/*comment without space*/").node
+ node = ProtoMultiLineComment.match("/*comment without space*/").node
self.assertEqual(node.value, "comment without space")
self.assertEqual(node.serialize(), "/*comment without space*/")
self.assertIsNone(node.normalize())
def test_does_not_match_partial_opening(self):
self.assertIsNone(
- ProtoMultiLineComment.match(None, "/hello there, this is a comment*/")
+ ProtoMultiLineComment.match("/hello there, this is a comment*/")
)
self.assertIsNone(
- ProtoMultiLineComment.match(None, "*/hello there, this is a comment*/")
+ ProtoMultiLineComment.match("*/hello there, this is a comment*/")
)
self.assertIsNone(
- ProtoMultiLineComment.match(None, "*hello there, this is a comment*/")
+ ProtoMultiLineComment.match("*hello there, this is a comment*/")
)
diff --git a/test/proto_constant_test.py b/test/proto_constant_test.py
index 3367770..fc3fd49 100644
--- a/test/proto_constant_test.py
+++ b/test/proto_constant_test.py
@@ -12,174 +12,160 @@
class ConstantTest(unittest.TestCase):
# constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) | strLit | boolLit
def test_ident(self):
+ self.assertEqual(ProtoConstant.match("a").node.value, ProtoIdentifier("a"))
+ self.assertEqual(ProtoConstant.match("a0").node.value, ProtoIdentifier("a0"))
+ self.assertEqual(ProtoConstant.match("a_").node.value, ProtoIdentifier("a_"))
+ self.assertEqual(ProtoConstant.match("aa").node.value, ProtoIdentifier("aa"))
+ self.assertEqual(ProtoConstant.match("ab").node.value, ProtoIdentifier("ab"))
self.assertEqual(
- ProtoConstant.match(None, "a").node.value, ProtoIdentifier(None, "a")
+ ProtoConstant.match("a0b_f_aj").node.value,
+ ProtoIdentifier("a0b_f_aj"),
)
self.assertEqual(
- ProtoConstant.match(None, "a0").node.value, ProtoIdentifier(None, "a0")
+ ProtoConstant.match("a.bar").node.value,
+ ProtoIdentifier("a.bar"),
)
self.assertEqual(
- ProtoConstant.match(None, "a_").node.value, ProtoIdentifier(None, "a_")
- )
- self.assertEqual(
- ProtoConstant.match(None, "aa").node.value, ProtoIdentifier(None, "aa")
- )
- self.assertEqual(
- ProtoConstant.match(None, "ab").node.value, ProtoIdentifier(None, "ab")
- )
- self.assertEqual(
- ProtoConstant.match(None, "a0b_f_aj").node.value,
- ProtoIdentifier(None, "a0b_f_aj"),
- )
- self.assertEqual(
- ProtoConstant.match(None, "a.bar").node.value,
- ProtoIdentifier(None, "a.bar"),
- )
- self.assertEqual(
- ProtoConstant.match(None, "a.bar.baz").node.value,
- ProtoIdentifier(None, "a.bar.baz"),
+ ProtoConstant.match("a.bar.baz").node.value,
+ ProtoIdentifier("a.bar.baz"),
)
def test_str(self):
self.assertEqual(
- ProtoConstant.match(None, "'a'").node.value,
- ProtoStringLiteral(None, "a", quote="'"),
+ ProtoConstant.match("'a'").node.value,
+ ProtoStringLiteral("a", quote="'"),
)
self.assertEqual(
- ProtoConstant.match(None, "'.a'").node.value,
- ProtoStringLiteral(None, ".a", quote="'"),
+ ProtoConstant.match("'.a'").node.value,
+ ProtoStringLiteral(".a", quote="'"),
)
self.assertEqual(
- ProtoConstant.match(None, '"a"').node.value,
- ProtoStringLiteral(None, "a", quote='"'),
+ ProtoConstant.match('"a"').node.value,
+ ProtoStringLiteral("a", quote='"'),
)
def test_bool(self):
- self.assertEqual(
- ProtoConstant.match(None, "true").node.value, ProtoBool(None, True)
- )
- self.assertEqual(
- ProtoConstant.match(None, "false").node.value, ProtoBool(None, False)
- )
+ self.assertEqual(ProtoConstant.match("true").node.value, ProtoBool(True))
+ self.assertEqual(ProtoConstant.match("false").node.value, ProtoBool(False))
def test_int(self):
self.assertEqual(
- ProtoConstant.match(None, "1").node.value,
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoConstant.match("1").node.value,
+ ProtoInt(1, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "158912938471293847").node.value,
- ProtoInt(None, 158912938471293847, ProtoIntSign.POSITIVE),
+ ProtoConstant.match("158912938471293847").node.value,
+ ProtoInt(158912938471293847, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "+1").node.value,
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoConstant.match("+1").node.value,
+ ProtoInt(1, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "+158912938471293847").node.value,
- ProtoInt(None, 158912938471293847, ProtoIntSign.POSITIVE),
+ ProtoConstant.match("+158912938471293847").node.value,
+ ProtoInt(158912938471293847, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "-1").node.value,
- ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
+ ProtoConstant.match("-1").node.value,
+ ProtoInt(1, ProtoIntSign.NEGATIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "-248713857").node.value,
- ProtoInt(None, 248713857, ProtoIntSign.NEGATIVE),
+ ProtoConstant.match("-248713857").node.value,
+ ProtoInt(248713857, ProtoIntSign.NEGATIVE),
)
# Octal
self.assertEqual(
- ProtoConstant.match(None, "072342").node.value,
- ProtoInt(None, 0o72342, ProtoIntSign.POSITIVE),
+ ProtoConstant.match("072342").node.value,
+ ProtoInt(0o72342, ProtoIntSign.POSITIVE),
)
with self.assertRaises(ValueError):
- ProtoConstant.match(None, "072942")
+ ProtoConstant.match("072942")
# Hex
self.assertEqual(
- ProtoConstant.match(None, "0x72342").node.value,
- ProtoInt(None, 0x72342, ProtoIntSign.POSITIVE),
+ ProtoConstant.match("0x72342").node.value,
+ ProtoInt(0x72342, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "0x7A3d2").node.value,
- ProtoInt(None, 0x7A3D2, ProtoIntSign.POSITIVE),
+ ProtoConstant.match("0x7A3d2").node.value,
+ ProtoInt(0x7A3D2, ProtoIntSign.POSITIVE),
)
with self.assertRaises(ValueError):
- ProtoConstant.match(None, "0x72G42")
+ ProtoConstant.match("0x72G42")
def test_float(self):
self.assertEqual(
- ProtoConstant.match(None, "2834.235928").node.value,
- ProtoFloat(None, 2834.235928, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834.235928").node.value,
+ ProtoFloat(2834.235928, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834.e2").node.value,
- ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834.e2").node.value,
+ ProtoFloat(283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834e2").node.value,
- ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834e2").node.value,
+ ProtoFloat(283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834.e0").node.value,
- ProtoFloat(None, 2834, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834.e0").node.value,
+ ProtoFloat(2834, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834e0").node.value,
- ProtoFloat(None, 2834, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834e0").node.value,
+ ProtoFloat(2834, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834.E3").node.value,
- ProtoFloat(None, 2834000, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834.E3").node.value,
+ ProtoFloat(2834000, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834E3").node.value,
- ProtoFloat(None, 2834000, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834E3").node.value,
+ ProtoFloat(2834000, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834.e+2").node.value,
- ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834.e+2").node.value,
+ ProtoFloat(283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834e+2").node.value,
- ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834e+2").node.value,
+ ProtoFloat(283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834.e-2").node.value,
- ProtoFloat(None, 28.34, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834.e-2").node.value,
+ ProtoFloat(28.34, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "2834e-2").node.value,
- ProtoFloat(None, 28.34, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("2834e-2").node.value,
+ ProtoFloat(28.34, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, ".0").node.value,
- ProtoFloat(None, 0.0, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(".0").node.value,
+ ProtoFloat(0.0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, ".0e-1").node.value,
- ProtoFloat(None, 0.00, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(".0e-1").node.value,
+ ProtoFloat(0.00, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, ".0E1").node.value,
- ProtoFloat(None, 0, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(".0E1").node.value,
+ ProtoFloat(0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, ".0E2").node.value,
- ProtoFloat(None, 0, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(".0E2").node.value,
+ ProtoFloat(0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, ".3265").node.value,
- ProtoFloat(None, 0.3265, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(".3265").node.value,
+ ProtoFloat(0.3265, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, ".3265e1").node.value,
- ProtoFloat(None, 3.265, ProtoFloatSign.POSITIVE),
+ ProtoConstant.match(".3265e1").node.value,
+ ProtoFloat(3.265, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoConstant.match(None, "inf").node.value,
- ProtoFloat(None, float("inf"), ProtoFloatSign.POSITIVE),
+ ProtoConstant.match("inf").node.value,
+ ProtoFloat(float("inf"), ProtoFloatSign.POSITIVE),
)
diff --git a/test/proto_enum_test.py b/test/proto_enum_test.py
index 095bad5..237aabc 100644
--- a/test/proto_enum_test.py
+++ b/test/proto_enum_test.py
@@ -27,7 +27,6 @@ class EnumTest(unittest.TestCase):
def test_enum_all_features(self):
parsed_enum_multiple_values = ProtoEnum.match(
- None,
dedent(
"""
enum FooEnum {
@@ -51,75 +50,61 @@ def test_enum_all_features(self):
parsed_enum_multiple_values.node.nodes,
[
ProtoReserved(
- None,
[
- ProtoRange(None, ProtoInt(None, 1, ProtoIntSign.POSITIVE)),
- ProtoRange(None, ProtoInt(None, 2, ProtoIntSign.POSITIVE)),
+ ProtoRange(ProtoInt(1, ProtoIntSign.POSITIVE)),
+ ProtoRange(ProtoInt(2, ProtoIntSign.POSITIVE)),
ProtoRange(
- None,
- ProtoInt(None, 5, ProtoIntSign.POSITIVE),
+ ProtoInt(5, ProtoIntSign.POSITIVE),
ProtoRangeEnum.MAX,
),
],
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_NEGATIVE"),
- ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
+ ProtoIdentifier("FE_NEGATIVE"),
+ ProtoInt(1, ProtoIntSign.NEGATIVE),
[
ProtoEnumValueOption(
- None,
- ProtoIdentifier(None, "foo"),
- ProtoConstant(None, ProtoBool(None, False)),
+ ProtoIdentifier("foo"),
+ ProtoConstant(ProtoBool(False)),
)
],
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNDEFINED"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNDEFINED"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
),
- ProtoSingleLineComment(None, " single-line comment"),
+ ProtoSingleLineComment(" single-line comment"),
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foobar")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foobar")),
),
ProtoMultiLineComment(
- None,
"\n multiple\n line\n comment\n ",
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_VALONE"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_VALONE"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
[
ProtoEnumValueOption(
- None,
- ProtoIdentifier(None, "(bar.baz).bat"),
- ProtoConstant(None, ProtoStringLiteral(None, "bat")),
+ ProtoIdentifier("(bar.baz).bat"),
+ ProtoConstant(ProtoStringLiteral("bat")),
),
ProtoEnumValueOption(
- None,
- ProtoIdentifier(None, "baz.bat"),
- ProtoConstant(
- None, ProtoInt(None, 100, ProtoIntSign.NEGATIVE)
- ),
+ ProtoIdentifier("baz.bat"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
),
],
),
ProtoReserved(
- None,
[],
[
- ProtoIdentifier(None, "FE_RESERVED"),
- ProtoIdentifier(None, "FE_OLD"),
+ ProtoIdentifier("FE_RESERVED"),
+ ProtoIdentifier("FE_OLD"),
],
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_VALTWO"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_VALTWO"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
],
)
@@ -148,12 +133,11 @@ def test_enum_all_features(self):
)
def test_empty_enum(self):
- parsed_empty_enum = ProtoEnum.match(None, """enum FooEnum {}""")
+ parsed_empty_enum = ProtoEnum.match("""enum FooEnum {}""")
self.assertIsNotNone(parsed_empty_enum)
- self.assertEqual(parsed_empty_enum.node.name, ProtoIdentifier(None, "FooEnum"))
+ self.assertEqual(parsed_empty_enum.node.name, ProtoIdentifier("FooEnum"))
parsed_spaced_enum = ProtoEnum.match(
- None,
dedent(
"""
enum FooEnum {
@@ -163,11 +147,10 @@ def test_empty_enum(self):
),
)
self.assertIsNotNone(parsed_spaced_enum)
- self.assertEqual(parsed_spaced_enum.node.name, ProtoIdentifier(None, "FooEnum"))
+ self.assertEqual(parsed_spaced_enum.node.name, ProtoIdentifier("FooEnum"))
def test_enum_empty_statements(self):
empty_statement_enum = ProtoEnum.match(
- None,
dedent(
"""
enum FooEnum {
@@ -178,13 +161,10 @@ def test_enum_empty_statements(self):
),
)
self.assertIsNotNone(empty_statement_enum)
- self.assertEqual(
- empty_statement_enum.node.name, ProtoIdentifier(None, "FooEnum")
- )
+ self.assertEqual(empty_statement_enum.node.name, ProtoIdentifier("FooEnum"))
def test_enum_optionals(self):
parsed_enum_with_optionals = ProtoEnum.match(
- None,
dedent(
"""
enum FooEnum {
@@ -198,24 +178,21 @@ def test_enum_optionals(self):
parsed_enum_with_optionals.node.options,
[
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foobar")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foobar")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "(foo.bar).baz"),
- ProtoConstant(None, ProtoBool(None, False)),
+ ProtoIdentifier("(foo.bar).baz"),
+ ProtoConstant(ProtoBool(False)),
),
],
)
self.assertEqual(
- parsed_enum_with_optionals.node.name, ProtoIdentifier(None, "FooEnum")
+ parsed_enum_with_optionals.node.name, ProtoIdentifier("FooEnum")
)
def test_enum_single_value(self):
parsed_enum_single_value = ProtoEnum.match(
- None,
dedent(
"""
enum FooEnum {
@@ -228,16 +205,14 @@ def test_enum_single_value(self):
parsed_enum_single_value.node.nodes,
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNDEFINED"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNDEFINED"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
)
def test_enum_multiple_values(self):
parsed_enum_multiple_values = ProtoEnum.match(
- None,
dedent(
"""
enum FooEnum {
@@ -253,31 +228,26 @@ def test_enum_multiple_values(self):
parsed_enum_multiple_values.node.nodes,
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_NEGATIVE"),
- ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
+ ProtoIdentifier("FE_NEGATIVE"),
+ ProtoInt(1, ProtoIntSign.NEGATIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNDEFINED"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNDEFINED"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_VALONE"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_VALONE"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_VALTWO"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_VALTWO"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
],
)
def test_enum_comments(self):
parsed_enum_multiple_values = ProtoEnum.match(
- None,
dedent(
"""
enum FooEnum {
@@ -295,36 +265,30 @@ def test_enum_comments(self):
parsed_enum_multiple_values.node.nodes,
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_NEGATIVE"),
- ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
+ ProtoIdentifier("FE_NEGATIVE"),
+ ProtoInt(1, ProtoIntSign.NEGATIVE),
),
- ProtoSingleLineComment(None, " test single-line comment"),
+ ProtoSingleLineComment(" test single-line comment"),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNDEFINED"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNDEFINED"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
),
ProtoMultiLineComment(
- None,
" test multiple\n FE_UNUSED = 200;\n line comment ",
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_VALONE"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_VALONE"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_VALTWO"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_VALTWO"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
],
)
def test_enum_normalize_away_comments(self):
parsed_enum_multiple_values = ProtoEnum.match(
- None,
dedent(
"""
enum FooEnum {
@@ -342,74 +306,62 @@ def test_enum_normalize_away_comments(self):
parsed_enum_multiple_values.nodes,
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_NEGATIVE"),
- ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
+ ProtoIdentifier("FE_NEGATIVE"),
+ ProtoInt(1, ProtoIntSign.NEGATIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNDEFINED"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNDEFINED"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_VALONE"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_VALONE"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_VALTWO"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_VALTWO"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
],
)
def test_diff_same_enum_returns_empty(self):
pe1 = ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[],
)
pe2 = ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[],
)
self.assertEqual(ProtoEnum.diff(pe1, pe2), [])
def test_diff_different_enum_name_returns_empty(self):
pe1 = ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[],
)
pe2 = ProtoEnum(
- None,
- ProtoIdentifier(None, "OtherEnum"),
+ ProtoIdentifier("OtherEnum"),
[],
)
self.assertEqual(ProtoEnum.diff(pe1, pe2), [])
def test_diff_different_enum_value_name_returns_enum_diff(self):
pe1 = ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
)
pe2 = ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_KNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_KNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
)
@@ -418,7 +370,7 @@ def test_diff_different_enum_value_name_returns_enum_diff(self):
ProtoEnumValueNameChanged(
pe1,
pe1.nodes[0],
- ProtoIdentifier(None, "ME_KNOWN"),
+ ProtoIdentifier("ME_KNOWN"),
)
],
ProtoEnum.diff(pe1, pe2),
@@ -426,24 +378,20 @@ def test_diff_different_enum_value_name_returns_enum_diff(self):
def test_diff_different_enum_value_value_returns_enum_diff(self):
pe1 = ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
)
pe2 = ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_UNKNOWN"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_UNKNOWN"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
)
],
)
@@ -469,13 +417,11 @@ def test_diff_different_enum_value_value_returns_enum_diff(self):
def test_diff_enum_added(self):
pe1 = None
pe2 = ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
)
@@ -484,13 +430,11 @@ def test_diff_enum_added(self):
[
ProtoEnumAdded(
ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
)
@@ -500,13 +444,11 @@ def test_diff_enum_added(self):
def test_diff_enum_removed(self):
pe1 = ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
)
@@ -516,13 +458,11 @@ def test_diff_enum_removed(self):
[
ProtoEnumRemoved(
ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
)
@@ -538,35 +478,29 @@ def test_diff_sets_empty_returns_empty(self):
def test_diff_sets_no_change(self):
set1 = [
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier("FooEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier("TagEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -577,35 +511,29 @@ def test_diff_sets_all_removed(self):
set1 = []
set2 = [
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier("FooEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier("TagEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -615,13 +543,11 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier("FooEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -631,13 +557,11 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -647,13 +571,11 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier("TagEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -665,35 +587,29 @@ def test_diff_sets_all_removed(self):
def test_diff_sets_all_added(self):
set1 = [
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier("FooEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier("TagEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -704,13 +620,11 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier("FooEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -720,13 +634,11 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -736,13 +648,11 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier("TagEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -754,70 +664,58 @@ def test_diff_sets_all_added(self):
def test_diff_sets_mutually_exclusive(self):
set1 = [
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier("FooEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier("TagEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
]
set2 = [
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum2"),
+ ProtoIdentifier("FooEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum2"),
+ ProtoIdentifier("BarEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum2"),
+ ProtoIdentifier("TagEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -828,13 +726,11 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier("FooEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -844,13 +740,11 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -861,13 +755,11 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier("TagEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -878,13 +770,11 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum2"),
+ ProtoIdentifier("FooEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -895,13 +785,11 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum2"),
+ ProtoIdentifier("BarEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -912,13 +800,11 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum2"),
+ ProtoIdentifier("TagEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -931,70 +817,58 @@ def test_diff_sets_mutually_exclusive(self):
def test_diff_sets_overlap(self):
set1 = [
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier("FooEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier("TagEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
]
set2 = [
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum2"),
+ ProtoIdentifier("FooEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum2"),
+ ProtoIdentifier("TagEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -1005,13 +879,11 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum"),
+ ProtoIdentifier("FooEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -1022,13 +894,11 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumRemoved(
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum"),
+ ProtoIdentifier("TagEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -1038,13 +908,11 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- None,
- ProtoIdentifier(None, "FooEnum2"),
+ ProtoIdentifier("FooEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "FE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("FE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -1054,13 +922,11 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumAdded(
ProtoEnum(
- None,
- ProtoIdentifier(None, "TagEnum2"),
+ ProtoIdentifier("TagEnum2"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "TE_UNKNOWN2"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("TE_UNKNOWN2"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
@@ -1070,22 +936,19 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumValueNameChanged(
ProtoEnum(
- None,
- ProtoIdentifier(None, "BarEnum"),
+ ProtoIdentifier("BarEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "BE_UNKNOWN"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("BE_UNKNOWN"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
),
- ProtoIdentifier(None, "BE_UNKNOWN2"),
+ ProtoIdentifier("BE_UNKNOWN2"),
),
diff,
)
diff --git a/test/proto_extend_test.py b/test/proto_extend_test.py
index 0bec941..176281a 100644
--- a/test/proto_extend_test.py
+++ b/test/proto_extend_test.py
@@ -11,16 +11,15 @@ class ExtendTest(unittest.TestCase):
maxDiff = None
def test_empty_extend(self):
- parsed_empty_extend = ProtoExtend.match(None, """extend FooMessage {}""")
+ parsed_empty_extend = ProtoExtend.match("""extend FooMessage {}""")
self.assertIsNotNone(parsed_empty_extend)
self.assertEqual(
parsed_empty_extend.node.name,
- ProtoEnumOrMessageIdentifier(None, "FooMessage"),
+ ProtoEnumOrMessageIdentifier("FooMessage"),
)
self.assertEqual(parsed_empty_extend.node.serialize(), "extend FooMessage {\n}")
parsed_spaced_extend = ProtoExtend.match(
- None,
dedent(
"""
extend FooMessage {
@@ -32,14 +31,13 @@ def test_empty_extend(self):
self.assertIsNotNone(parsed_spaced_extend)
self.assertEqual(
parsed_spaced_extend.node.name,
- ProtoEnumOrMessageIdentifier(None, "FooMessage"),
+ ProtoEnumOrMessageIdentifier("FooMessage"),
)
self.assertEqual(
parsed_spaced_extend.node.serialize(), "extend FooMessage {\n}"
)
parsed_scoped_extend = ProtoExtend.match(
- None,
dedent(
"""
extend google.protobuf.FooMessage {
@@ -51,7 +49,7 @@ def test_empty_extend(self):
self.assertIsNotNone(parsed_scoped_extend)
self.assertEqual(
parsed_scoped_extend.node.name,
- ProtoEnumOrMessageIdentifier(None, "google.protobuf.FooMessage"),
+ ProtoEnumOrMessageIdentifier("google.protobuf.FooMessage"),
)
self.assertEqual(
parsed_scoped_extend.node.serialize(),
@@ -60,7 +58,6 @@ def test_empty_extend(self):
def test_extend_empty_statements(self):
empty_statement_message = ProtoExtend.match(
- None,
dedent(
"""
extend FooMessage {
@@ -73,7 +70,7 @@ def test_extend_empty_statements(self):
self.assertIsNotNone(empty_statement_message)
self.assertEqual(
empty_statement_message.node.name,
- ProtoEnumOrMessageIdentifier(None, "FooMessage"),
+ ProtoEnumOrMessageIdentifier("FooMessage"),
)
self.assertEqual(
empty_statement_message.node.serialize(), "extend FooMessage {\n}"
@@ -81,7 +78,6 @@ def test_extend_empty_statements(self):
def test_extend_simple_field(self):
parsed_extend_with_single_field = ProtoExtend.match(
- None,
dedent(
"""
extend FooMessage {
@@ -93,14 +89,12 @@ def test_extend_simple_field(self):
self.assertEqual(
parsed_extend_with_single_field.node,
ProtoExtend(
- None,
- ProtoEnumOrMessageIdentifier(None, "FooMessage"),
+ ProtoEnumOrMessageIdentifier("FooMessage"),
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "single_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("single_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
)
],
),
diff --git a/test/proto_extensions_test.py b/test/proto_extensions_test.py
index 86f64c4..50f0723 100644
--- a/test/proto_extensions_test.py
+++ b/test/proto_extensions_test.py
@@ -6,29 +6,29 @@
class ExtensionsTest(unittest.TestCase):
def test_extension_single_int(self):
self.assertEqual(
- ProtoExtensions.match(None, "extensions 21;").node.serialize(),
+ ProtoExtensions.match("extensions 21;").node.serialize(),
"extensions 21;",
)
self.assertEqual(
- ProtoExtensions.match(None, "extensions -1;").node.serialize(),
+ ProtoExtensions.match("extensions -1;").node.serialize(),
"extensions -1;",
)
def test_extension_multiple_ints(self):
self.assertEqual(
- ProtoExtensions.match(None, "extensions 1, 5, 2, 42;").node.serialize(),
+ ProtoExtensions.match("extensions 1, 5, 2, 42;").node.serialize(),
"extensions 1, 5, 2, 42;",
)
def test_extension_with_max(self):
self.assertEqual(
- ProtoExtensions.match(None, "extensions 8 to max;").node.serialize(),
+ ProtoExtensions.match("extensions 8 to max;").node.serialize(),
"extensions 8 to max;",
)
def test_extension_cannot_have_strings(self):
- self.assertIsNone(ProtoExtensions.match(None, "extensions 1, 'foo';"))
- self.assertIsNone(ProtoExtensions.match(None, "extensions 'bar';"))
+ self.assertIsNone(ProtoExtensions.match("extensions 1, 'foo';"))
+ self.assertIsNone(ProtoExtensions.match("extensions 'bar';"))
if __name__ == "__main__":
diff --git a/test/proto_float_test.py b/test/proto_float_test.py
index 28eb34e..ecdbe22 100644
--- a/test/proto_float_test.py
+++ b/test/proto_float_test.py
@@ -6,88 +6,88 @@
class FloatTest(unittest.TestCase):
def test_float(self):
self.assertEqual(
- ProtoFloat.match(None, "2834.235928").node,
- ProtoFloat(None, 2834.235928, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834.235928").node,
+ ProtoFloat(2834.235928, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, ".0").node,
- ProtoFloat(None, 0.0, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(".0").node,
+ ProtoFloat(0.0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, ".3265").node,
- ProtoFloat(None, 0.3265, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(".3265").node,
+ ProtoFloat(0.3265, ProtoFloatSign.POSITIVE),
)
def test_inf(self):
self.assertEqual(
- ProtoFloat.match(None, "inf").node,
- ProtoFloat(None, float("inf"), ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("inf").node,
+ ProtoFloat(float("inf"), ProtoFloatSign.POSITIVE),
)
def test_nan(self):
- match = ProtoFloat.match(None, "nan")
+ match = ProtoFloat.match("nan")
self.assertNotEqual(match.node.value, match.node.value)
self.assertEqual(match.remaining_source, "")
self.assertEqual(match.node.sign, ProtoFloatSign.POSITIVE)
def test_exponential_positive(self):
self.assertEqual(
- ProtoFloat.match(None, "2834.e2").node,
- ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834.e2").node,
+ ProtoFloat(283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, "2834e2").node,
- ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834e2").node,
+ ProtoFloat(283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, "2834.e0").node,
- ProtoFloat(None, 2834, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834.e0").node,
+ ProtoFloat(2834, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, "2834e0").node,
- ProtoFloat(None, 2834, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834e0").node,
+ ProtoFloat(2834, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, "2834.E3").node,
- ProtoFloat(None, 2834000, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834.E3").node,
+ ProtoFloat(2834000, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, "2834E3").node,
- ProtoFloat(None, 2834000, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834E3").node,
+ ProtoFloat(2834000, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, "2834.e+2").node,
- ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834.e+2").node,
+ ProtoFloat(283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, "2834e+2").node,
- ProtoFloat(None, 283400, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834e+2").node,
+ ProtoFloat(283400, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, ".0E1").node,
- ProtoFloat(None, 0, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(".0E1").node,
+ ProtoFloat(0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, ".0E2").node,
- ProtoFloat(None, 0, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(".0E2").node,
+ ProtoFloat(0, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, ".3265e1").node,
- ProtoFloat(None, 3.265, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(".3265e1").node,
+ ProtoFloat(3.265, ProtoFloatSign.POSITIVE),
)
def test_exponential_negative(self):
self.assertEqual(
- ProtoFloat.match(None, "2834.e-2").node,
- ProtoFloat(None, 28.34, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834.e-2").node,
+ ProtoFloat(28.34, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, "2834e-2").node,
- ProtoFloat(None, 28.34, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match("2834e-2").node,
+ ProtoFloat(28.34, ProtoFloatSign.POSITIVE),
)
self.assertEqual(
- ProtoFloat.match(None, ".0e-1").node,
- ProtoFloat(None, 0.00, ProtoFloatSign.POSITIVE),
+ ProtoFloat.match(".0e-1").node,
+ ProtoFloat(0.00, ProtoFloatSign.POSITIVE),
)
diff --git a/test/proto_identifier_test.py b/test/proto_identifier_test.py
index d1f44d3..dd5435f 100644
--- a/test/proto_identifier_test.py
+++ b/test/proto_identifier_test.py
@@ -10,99 +10,89 @@
class IdentifierTest(unittest.TestCase):
def test_ident(self):
- self.assertEqual(ProtoIdentifier.match(None, "a").node.identifier, "a")
- self.assertEqual(ProtoIdentifier.match(None, "a0").node.identifier, "a0")
- self.assertEqual(ProtoIdentifier.match(None, "a_").node.identifier, "a_")
- self.assertEqual(ProtoIdentifier.match(None, "aa").node.identifier, "aa")
- self.assertEqual(ProtoIdentifier.match(None, "ab").node.identifier, "ab")
- self.assertEqual(
- ProtoIdentifier.match(None, "a0b_f_aj").node.identifier, "a0b_f_aj"
- )
+ self.assertEqual(ProtoIdentifier.match("a").node.identifier, "a")
+ self.assertEqual(ProtoIdentifier.match("a0").node.identifier, "a0")
+ self.assertEqual(ProtoIdentifier.match("a_").node.identifier, "a_")
+ self.assertEqual(ProtoIdentifier.match("aa").node.identifier, "aa")
+ self.assertEqual(ProtoIdentifier.match("ab").node.identifier, "ab")
+ self.assertEqual(ProtoIdentifier.match("a0b_f_aj").node.identifier, "a0b_f_aj")
def test_ident_no_leading_letter(self):
- self.assertIsNone(ProtoIdentifier.match(None, "0"))
- self.assertIsNone(ProtoIdentifier.match(None, "0abc_ab"))
- self.assertIsNone(ProtoIdentifier.match(None, "0_ab_0a_a0"))
- self.assertIsNone(ProtoIdentifier.match(None, " "))
- self.assertIsNone(ProtoIdentifier.match(None, " abc"))
- self.assertIsNone(ProtoIdentifier.match(None, "\nabc"))
- self.assertIsNone(ProtoIdentifier.match(None, "\n abc"))
- self.assertIsNone(ProtoIdentifier.match(None, "\tabc"))
- self.assertIsNone(ProtoIdentifier.match(None, "\n\tabc"))
- self.assertIsNone(ProtoIdentifier.match(None, "\t\nabc"))
- self.assertIsNone(ProtoIdentifier.match(None, "\t\n abc"))
- self.assertIsNone(ProtoIdentifier.match(None, ".a"))
- self.assertIsNone(ProtoIdentifier.match(None, " .a"))
- self.assertIsNone(ProtoIdentifier.match(None, "."))
- self.assertIsNone(ProtoIdentifier.match(None, ".0"))
+ self.assertIsNone(ProtoIdentifier.match("0"))
+ self.assertIsNone(ProtoIdentifier.match("0abc_ab"))
+ self.assertIsNone(ProtoIdentifier.match("0_ab_0a_a0"))
+ self.assertIsNone(ProtoIdentifier.match(" "))
+ self.assertIsNone(ProtoIdentifier.match(" abc"))
+ self.assertIsNone(ProtoIdentifier.match("\nabc"))
+ self.assertIsNone(ProtoIdentifier.match("\n abc"))
+ self.assertIsNone(ProtoIdentifier.match("\tabc"))
+ self.assertIsNone(ProtoIdentifier.match("\n\tabc"))
+ self.assertIsNone(ProtoIdentifier.match("\t\nabc"))
+ self.assertIsNone(ProtoIdentifier.match("\t\n abc"))
+ self.assertIsNone(ProtoIdentifier.match(".a"))
+ self.assertIsNone(ProtoIdentifier.match(" .a"))
+ self.assertIsNone(ProtoIdentifier.match("."))
+ self.assertIsNone(ProtoIdentifier.match(".0"))
def test_full_ident(self):
- self.assertEqual(ProtoFullIdentifier.match(None, "a").node.identifier, "a")
- self.assertEqual(
- ProtoFullIdentifier.match(None, "a.bar").node.identifier, "a.bar"
- )
+ self.assertEqual(ProtoFullIdentifier.match("a").node.identifier, "a")
+ self.assertEqual(ProtoFullIdentifier.match("a.bar").node.identifier, "a.bar")
self.assertEqual(
- ProtoFullIdentifier.match(None, "a.bar.baz").node.identifier, "a.bar.baz"
+ ProtoFullIdentifier.match("a.bar.baz").node.identifier, "a.bar.baz"
)
self.assertEqual(
- ProtoFullIdentifier.match(None, "a.bar.b0").node.identifier, "a.bar.b0"
+ ProtoFullIdentifier.match("a.bar.b0").node.identifier, "a.bar.b0"
)
self.assertEqual(
- ProtoFullIdentifier.match(None, "a.bar.b0.c_2a").node.identifier,
+ ProtoFullIdentifier.match("a.bar.b0.c_2a").node.identifier,
"a.bar.b0.c_2a",
)
def test_full_ident_invalid_periods(self):
with self.assertRaises(ValueError):
- ProtoFullIdentifier.match(None, "a.")
+ ProtoFullIdentifier.match("a.")
with self.assertRaises(ValueError):
- ProtoFullIdentifier.match(None, "a.bar.")
+ ProtoFullIdentifier.match("a.bar.")
with self.assertRaises(ValueError):
- ProtoFullIdentifier.match(None, "a..")
+ ProtoFullIdentifier.match("a..")
def test_message_type(self):
+ self.assertEqual(ProtoEnumOrMessageIdentifier.match("a").node.identifier, "a")
+ self.assertEqual(ProtoEnumOrMessageIdentifier.match(".a").node.identifier, ".a")
self.assertEqual(
- ProtoEnumOrMessageIdentifier.match(None, "a").node.identifier, "a"
- )
- self.assertEqual(
- ProtoEnumOrMessageIdentifier.match(None, ".a").node.identifier, ".a"
- )
- self.assertEqual(
- ProtoEnumOrMessageIdentifier.match(None, ".a.bar").node.identifier, ".a.bar"
+ ProtoEnumOrMessageIdentifier.match(".a.bar").node.identifier, ".a.bar"
)
self.assertEqual(
- ProtoEnumOrMessageIdentifier.match(None, "a.bar").node.identifier, "a.bar"
+ ProtoEnumOrMessageIdentifier.match("a.bar").node.identifier, "a.bar"
)
def test_identifier_serialize(self):
- self.assertEqual(ProtoIdentifier.match(None, "a").node.serialize(), "a")
- self.assertEqual(ProtoIdentifier.match(None, "a0").node.serialize(), "a0")
+ self.assertEqual(ProtoIdentifier.match("a").node.serialize(), "a")
+ self.assertEqual(ProtoIdentifier.match("a0").node.serialize(), "a0")
self.assertEqual(
- ProtoIdentifier.match(None, "a_").node.serialize(),
+ ProtoIdentifier.match("a_").node.serialize(),
"a_",
)
self.assertEqual(
- ProtoIdentifier.match(None, "a0_foo_ba0_0baz").node.serialize(),
+ ProtoIdentifier.match("a0_foo_ba0_0baz").node.serialize(),
"a0_foo_ba0_0baz",
)
self.assertEqual(
- ProtoFullIdentifier.match(None, "a.bar").node.serialize(),
+ ProtoFullIdentifier.match("a.bar").node.serialize(),
"a.bar",
)
self.assertEqual(
- ProtoFullIdentifier.match(None, "a.bar_baz.foo0").node.serialize(),
+ ProtoFullIdentifier.match("a.bar_baz.foo0").node.serialize(),
"a.bar_baz.foo0",
)
self.assertEqual(
- ProtoEnumOrMessageIdentifier.match(None, ".a").node.serialize(),
+ ProtoEnumOrMessageIdentifier.match(".a").node.serialize(),
".a",
)
self.assertEqual(
- ProtoEnumOrMessageIdentifier.match(
- None, ".a.bar0_baz.foo"
- ).node.serialize(),
+ ProtoEnumOrMessageIdentifier.match(".a.bar0_baz.foo").node.serialize(),
".a.bar0_baz.foo",
)
diff --git a/test/proto_import_test.py b/test/proto_import_test.py
index 994ec22..8806d8f 100644
--- a/test/proto_import_test.py
+++ b/test/proto_import_test.py
@@ -13,14 +13,14 @@
class ImportTest(unittest.TestCase):
def test_bare_import(self):
- double_quote_import = ProtoImport.match(None, 'import "foo.proto";')
+ double_quote_import = ProtoImport.match('import "foo.proto";')
self.assertEqual(double_quote_import.node.path.value, "foo.proto")
self.assertEqual(double_quote_import.node.weak, False)
self.assertEqual(double_quote_import.node.public, False)
self.assertEqual(double_quote_import.node.serialize(), 'import "foo.proto";')
self.assertEqual(double_quote_import.remaining_source, "")
- single_quote_import = ProtoImport.match(None, "import 'foo.proto';")
+ single_quote_import = ProtoImport.match("import 'foo.proto';")
self.assertEqual(single_quote_import.node.path.value, "foo.proto")
self.assertEqual(single_quote_import.node.weak, False)
self.assertEqual(single_quote_import.node.public, False)
@@ -29,29 +29,29 @@ def test_bare_import(self):
def test_import_missing_semicolon(self):
with self.assertRaises(ValueError):
- ProtoImport.match(None, 'import "foo.proto"')
+ ProtoImport.match('import "foo.proto"')
def test_import_missing_starting_quote(self):
with self.assertRaises(ValueError):
- ProtoImport.match(None, 'import foo.proto";')
+ ProtoImport.match('import foo.proto";')
with self.assertRaises(ValueError):
- ProtoImport.match(None, "import foo.proto';")
+ ProtoImport.match("import foo.proto';")
def test_import_missing_ending_quote(self):
with self.assertRaises(ValueError):
- ProtoImport.match(None, 'import "foo.proto;')
+ ProtoImport.match('import "foo.proto;')
with self.assertRaises(ValueError):
- ProtoImport.match(None, "import 'foo.proto;")
+ ProtoImport.match("import 'foo.proto;")
def test_weak_import(self):
- double_quote_import = ProtoImport.match(None, 'import weak "foo.proto";')
+ double_quote_import = ProtoImport.match('import weak "foo.proto";')
self.assertEqual(double_quote_import.node.weak, True)
self.assertEqual(
double_quote_import.node.serialize(), 'import weak "foo.proto";'
)
- double_quote_import = ProtoImport.match(None, "import weak 'foo.proto';")
+ double_quote_import = ProtoImport.match("import weak 'foo.proto';")
self.assertEqual(double_quote_import.node.weak, True)
self.assertEqual(
double_quote_import.node.serialize(), "import weak 'foo.proto';"
@@ -59,11 +59,10 @@ def test_weak_import(self):
def test_weak_typoed_import(self):
with self.assertRaises(ValueError):
- ProtoImport.match(None, 'import weac "foo.proto";')
+ ProtoImport.match('import weac "foo.proto";')
def test_weak_mixed_imports(self):
first_parsed_import = ProtoImport.match(
- None,
dedent(
"""import "foo.proto";
import weak "bar/baz.proto";
@@ -74,30 +73,26 @@ def test_weak_mixed_imports(self):
self.assertEqual(first_parsed_import.node.weak, False)
self.assertEqual(first_parsed_import.node.serialize(), 'import "foo.proto";')
- second_parsed_import = ProtoImport.match(
- None, first_parsed_import.remaining_source
- )
+ second_parsed_import = ProtoImport.match(first_parsed_import.remaining_source)
self.assertEqual(second_parsed_import.node.path.value, "bar/baz.proto")
self.assertEqual(second_parsed_import.node.weak, True)
self.assertEqual(
second_parsed_import.node.serialize(), 'import weak "bar/baz.proto";'
)
- third_parsed_import = ProtoImport.match(
- None, second_parsed_import.remaining_source
- )
+ third_parsed_import = ProtoImport.match(second_parsed_import.remaining_source)
self.assertEqual(third_parsed_import.node.path.value, "bat.proto")
self.assertEqual(third_parsed_import.node.weak, False)
self.assertEqual(third_parsed_import.node.serialize(), 'import "bat.proto";')
def test_public_import(self):
- double_quote_import = ProtoImport.match(None, 'import public "foo.proto";')
+ double_quote_import = ProtoImport.match('import public "foo.proto";')
self.assertEqual(double_quote_import.node.public, True)
self.assertEqual(
double_quote_import.node.serialize(), 'import public "foo.proto";'
)
- single_quote_import = ProtoImport.match(None, "import public 'foo.proto';")
+ single_quote_import = ProtoImport.match("import public 'foo.proto';")
self.assertEqual(single_quote_import.node.public, True)
self.assertEqual(
single_quote_import.node.serialize(), "import public 'foo.proto';"
@@ -105,18 +100,17 @@ def test_public_import(self):
def test_public_typoed_import(self):
with self.assertRaises(ValueError):
- ProtoImport.match(None, 'import publik "foo.proto";')
+ ProtoImport.match('import publik "foo.proto";')
def test_public_weak_mutually_exclusive(self):
with self.assertRaises(ValueError):
- ProtoImport.match(None, 'import weak public "foo.proto";')
+ ProtoImport.match('import weak public "foo.proto";')
with self.assertRaises(ValueError):
- ProtoImport.match(None, 'import public weak "foo.proto";')
+ ProtoImport.match('import public weak "foo.proto";')
def test_public_mixed_imports(self):
first_parsed_import = ProtoImport.match(
- None,
dedent(
"""import "foo.proto";
import public "bar/baz.proto";
@@ -127,18 +121,14 @@ def test_public_mixed_imports(self):
self.assertEqual(first_parsed_import.node.public, False)
self.assertEqual(first_parsed_import.node.serialize(), 'import "foo.proto";')
- second_parsed_import = ProtoImport.match(
- None, first_parsed_import.remaining_source
- )
+ second_parsed_import = ProtoImport.match(first_parsed_import.remaining_source)
self.assertEqual(second_parsed_import.node.path.value, "bar/baz.proto")
self.assertEqual(second_parsed_import.node.public, True)
self.assertEqual(
second_parsed_import.node.serialize(), 'import public "bar/baz.proto";'
)
- third_parsed_import = ProtoImport.match(
- None, second_parsed_import.remaining_source
- )
+ third_parsed_import = ProtoImport.match(second_parsed_import.remaining_source)
self.assertEqual(third_parsed_import.node.path.value, "bat.proto")
self.assertEqual(third_parsed_import.node.public, True)
self.assertEqual(
@@ -146,21 +136,21 @@ def test_public_mixed_imports(self):
)
def test_diff_sets_same_path_simple(self):
- pf1 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
- pf2 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
+ pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ pf2 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
self.assertEqual(ProtoImport.diff_sets([pf1], [pf2]), [])
def test_diff_sets_added_path_simple(self):
- pf1 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
+ pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
self.assertEqual(ProtoImport.diff_sets([pf1], []), [ProtoImportAdded(pf1)])
def test_diff_sets_removed_path_simple(self):
- pf2 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
+ pf2 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
self.assertEqual(ProtoImport.diff_sets([], [pf2]), [ProtoImportRemoved(pf2)])
def test_diff_sets_different_path_simple(self):
- pf1 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some.proto"))
- pf2 = ProtoImport(None, ProtoStringLiteral(None, "path/to/some/other.proto"))
+ pf1 = ProtoImport(ProtoStringLiteral("path/to/some.proto"))
+ pf2 = ProtoImport(ProtoStringLiteral("path/to/some/other.proto"))
self.assertEqual(
ProtoImport.diff_sets([pf1], [pf2]),
[ProtoImportAdded(pf1), ProtoImportRemoved(pf2)],
@@ -168,14 +158,12 @@ def test_diff_sets_different_path_simple(self):
def test_diff_sets_changed_optional_attributes(self):
pf1 = ProtoImport(
- None,
- ProtoStringLiteral(None, "path/to/some.proto"),
+ ProtoStringLiteral("path/to/some.proto"),
weak=False,
public=True,
)
pf2 = ProtoImport(
- None,
- ProtoStringLiteral(None, "path/to/some.proto"),
+ ProtoStringLiteral("path/to/some.proto"),
weak=True,
public=False,
)
diff --git a/test/proto_int_test.py b/test/proto_int_test.py
index 0aaf7f7..3293d5e 100644
--- a/test/proto_int_test.py
+++ b/test/proto_int_test.py
@@ -5,33 +5,31 @@
class IntTest(unittest.TestCase):
def test_int(self):
+ self.assertEqual(ProtoInt.match("1").node, ProtoInt(1, ProtoIntSign.POSITIVE))
self.assertEqual(
- ProtoInt.match(None, "1").node, ProtoInt(None, 1, ProtoIntSign.POSITIVE)
- )
- self.assertEqual(
- ProtoInt.match(None, "158912938471293847").node,
- ProtoInt(None, 158912938471293847, ProtoIntSign.POSITIVE),
+ ProtoInt.match("158912938471293847").node,
+ ProtoInt(158912938471293847, ProtoIntSign.POSITIVE),
)
def test_octal(self):
self.assertEqual(
- ProtoInt.match(None, "072342").node,
- ProtoInt(None, 0o72342, ProtoIntSign.POSITIVE),
+ ProtoInt.match("072342").node,
+ ProtoInt(0o72342, ProtoIntSign.POSITIVE),
)
with self.assertRaises(ValueError):
- ProtoInt.match(None, "072942")
+ ProtoInt.match("072942")
def test_hex(self):
self.assertEqual(
- ProtoInt.match(None, "0x72342").node,
- ProtoInt(None, 0x72342, ProtoIntSign.POSITIVE),
+ ProtoInt.match("0x72342").node,
+ ProtoInt(0x72342, ProtoIntSign.POSITIVE),
)
self.assertEqual(
- ProtoInt.match(None, "0x7A3d2").node,
- ProtoInt(None, 0x7A3D2, ProtoIntSign.POSITIVE),
+ ProtoInt.match("0x7A3d2").node,
+ ProtoInt(0x7A3D2, ProtoIntSign.POSITIVE),
)
with self.assertRaises(ValueError):
- ProtoInt.match(None, "0x72G42")
+ ProtoInt.match("0x72G42")
if __name__ == "__main__":
diff --git a/test/proto_map_test.py b/test/proto_map_test.py
index b67c424..59e7ba1 100644
--- a/test/proto_map_test.py
+++ b/test/proto_map_test.py
@@ -16,84 +16,72 @@ class MapTest(unittest.TestCase):
maxDiff = None
def test_simple_map(self):
- parsed_map_simple = ProtoMap.match(
- None, "map my_map = 10;"
- )
+ parsed_map_simple = ProtoMap.match("map my_map = 10;")
self.assertEqual(
parsed_map_simple.node,
ProtoMap(
- None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "my_map"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ ProtoIdentifier("my_map"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier("NestedMessage"),
[],
),
)
def test_map_without_spaces(self):
- map_without_spaces = ProtoMap.match(
- None, "map my_map = 10;"
- )
+ map_without_spaces = ProtoMap.match("map my_map = 10;")
self.assertEqual(
map_without_spaces.node,
ProtoMap(
- None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "my_map"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ ProtoIdentifier("my_map"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier("NestedMessage"),
[],
),
)
def test_map_with_options(self):
parsed_map_simple = ProtoMap.match(
- None,
"map my_map = 10 [ java_package = 'com.example.foo', baz.bat = 48 ];",
)
self.assertEqual(parsed_map_simple.node.key_type, ProtoMapKeyTypesEnum.SFIXED64)
self.assertEqual(
parsed_map_simple.node.value_type, ProtoMapValueTypesEnum.ENUM_OR_MESSAGE
)
- self.assertEqual(parsed_map_simple.node.name, ProtoIdentifier(None, "my_map"))
+ self.assertEqual(parsed_map_simple.node.name, ProtoIdentifier("my_map"))
self.assertEqual(
- parsed_map_simple.node.number, ProtoInt(None, 10, ProtoIntSign.POSITIVE)
+ parsed_map_simple.node.number, ProtoInt(10, ProtoIntSign.POSITIVE)
)
self.assertEqual(
parsed_map_simple.node.enum_or_message_type_name,
- ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ ProtoEnumOrMessageIdentifier("NestedMessage"),
)
self.assertEqual(
parsed_map_simple.node.options,
[
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "com.example.foo")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
),
ProtoMessageFieldOption(
- None,
- ProtoFullIdentifier(None, "baz.bat"),
- ProtoConstant(None, ProtoInt(None, 48, ProtoIntSign.POSITIVE)),
+ ProtoFullIdentifier("baz.bat"),
+ ProtoConstant(ProtoInt(48, ProtoIntSign.POSITIVE)),
),
],
)
def test_map_message_value(self):
- parsed_map_simple = ProtoMap.match(
- None, "map string_map = 11;"
- )
+ parsed_map_simple = ProtoMap.match("map string_map = 11;")
self.assertEqual(
parsed_map_simple.node,
ProtoMap(
- None,
ProtoMapKeyTypesEnum.STRING,
ProtoMapValueTypesEnum.STRING,
- ProtoIdentifier(None, "string_map"),
- ProtoInt(None, 11, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("string_map"),
+ ProtoInt(11, ProtoIntSign.POSITIVE),
None,
[],
),
diff --git a/test/proto_message_field_test.py b/test/proto_message_field_test.py
index 26c82e6..fa6a882 100644
--- a/test/proto_message_field_test.py
+++ b/test/proto_message_field_test.py
@@ -19,14 +19,13 @@ class MessageFieldTest(unittest.TestCase):
maxDiff = None
def test_field_optional_default_false(self):
- string_field = ProtoMessageField.match(None, "string single_field = 1;")
+ string_field = ProtoMessageField.match("string single_field = 1;")
self.assertEqual(
string_field.node,
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "single_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("single_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
False,
False,
),
@@ -34,15 +33,14 @@ def test_field_optional_default_false(self):
def test_field_optional_set(self):
string_field = ProtoMessageField.match(
- None, "optional string single_field = 1;".strip()
+ "optional string single_field = 1;".strip()
)
self.assertEqual(
string_field.node,
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "single_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("single_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
False,
True,
),
@@ -51,116 +49,104 @@ def test_field_optional_set(self):
def test_field_cannot_have_repeated_and_optional(self):
with self.assertRaises(ValueError):
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "single_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("single_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
True,
True,
)
def test_message_field_starts_with_underscore(self):
- parsed_undescored_field = ProtoMessageField.match(
- None, "string _test_field = 1;"
- )
+ parsed_undescored_field = ProtoMessageField.match("string _test_field = 1;")
self.assertEqual(
parsed_undescored_field.node,
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "_test_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("_test_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
)
parsed_double_undescored_field = ProtoMessageField.match(
- None, "bool __test_field = 1;"
+ "bool __test_field = 1;"
)
self.assertEqual(
parsed_double_undescored_field.node,
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.BOOL,
- ProtoIdentifier(None, "__test_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("__test_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
)
def test_field_repeated(self):
parsed_message_with_repeated_field_simple = ProtoMessageField.match(
- None, "repeated bool repeated_field = 3;"
+ "repeated bool repeated_field = 3;"
)
self.assertEqual(
parsed_message_with_repeated_field_simple.node,
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.BOOL,
- ProtoIdentifier(None, "repeated_field"),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("repeated_field"),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
True,
),
)
def test_field_enum_or_message(self):
parsed_message_with_repeated_field_simple = ProtoMessageField.match(
- None, "foo.SomeEnumOrMessage enum_or_message_field = 1;"
+ "foo.SomeEnumOrMessage enum_or_message_field = 1;"
)
self.assertEqual(
parsed_message_with_repeated_field_simple.node,
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "enum_or_message_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("enum_or_message_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier(None, "foo.SomeEnumOrMessage"),
+ ProtoFullIdentifier("foo.SomeEnumOrMessage"),
),
)
def test_field_starts_with_period(self):
parsed_field_with_type_starting_with_period = ProtoMessageField.match(
- None, ".google.proto.FooType enum_or_message_field = 1;"
+ ".google.proto.FooType enum_or_message_field = 1;"
)
self.assertEqual(
parsed_field_with_type_starting_with_period.node,
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "enum_or_message_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("enum_or_message_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
False,
False,
- ProtoEnumOrMessageIdentifier(None, ".google.proto.FooType"),
+ ProtoEnumOrMessageIdentifier(".google.proto.FooType"),
),
)
def test_diff_same_field_returns_empty(self):
pmf1 = ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "my_message_field"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("my_message_field"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
)
pmf2 = ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "my_message_field"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("my_message_field"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
)
self.assertEqual(ProtoMessageField.diff(None, pmf1, pmf2), [])
def test_diff_different_field_name_same_number_returns_field_diff(self):
pmf1 = ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
)
pmf2 = ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "bar"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
)
self.assertEqual(
[
@@ -175,10 +161,9 @@ def test_diff_different_field_name_same_number_returns_field_diff(self):
def test_diff_field_removed(self):
pmf1 = ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
)
pmf2 = None
self.assertEqual(
@@ -196,22 +181,19 @@ def test_diff_sets_empty_returns_empty(self):
def test_diff_sets_no_change(self):
set1 = [
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "bar"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "baz"),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("baz"),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
),
]
self.assertEqual([], ProtoMessageField.diff_sets(None, set1, set1))
@@ -220,22 +202,19 @@ def test_diff_sets_all_removed(self):
set1 = []
set2 = [
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "bar"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "baz"),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("baz"),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
),
]
diff = ProtoMessageField.diff_sets(None, set1, set2)
@@ -250,22 +229,19 @@ def test_diff_sets_all_removed(self):
def test_diff_sets_all_added(self):
set1 = [
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "bar"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "baz"),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("baz"),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
),
]
set2 = []
@@ -282,42 +258,36 @@ def test_diff_sets_all_added(self):
def test_diff_sets_mutually_exclusive(self):
set1 = [
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "bar"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "baz"),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("baz"),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
),
]
set2 = [
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "foo2"),
- ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo2"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "bar2"),
- ProtoInt(None, 5, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar2"),
+ ProtoInt(5, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "baz2"),
- ProtoInt(None, 6, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("baz2"),
+ ProtoInt(6, ProtoIntSign.POSITIVE),
),
]
@@ -340,42 +310,36 @@ def test_diff_sets_mutually_exclusive(self):
def test_diff_sets_overlap(self):
set1 = [
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "bar"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "baz"),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("baz"),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
),
]
set2 = [
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "foo2"),
- ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo2"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "bar"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.FLOAT,
- ProtoIdentifier(None, "baz2"),
- ProtoInt(None, 6, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("baz2"),
+ ProtoInt(6, ProtoIntSign.POSITIVE),
),
]
diff --git a/test/proto_message_test.py b/test/proto_message_test.py
index 9e0f684..fa4a5ae 100644
--- a/test/proto_message_test.py
+++ b/test/proto_message_test.py
@@ -36,7 +36,6 @@ class MessageTest(unittest.TestCase):
def test_message_all_features(self):
parsed_message_multiple_fields = ProtoMessage.match(
- None,
dedent(
"""
message FooMessage {
@@ -68,152 +67,119 @@ def test_message_all_features(self):
parsed_message_multiple_fields.node.nodes,
[
ProtoOption(
- None,
- ProtoIdentifier(None, "(foo.bar).baz"),
- ProtoConstant(None, ProtoStringLiteral(None, "bat")),
+ ProtoIdentifier("(foo.bar).baz"),
+ ProtoConstant(ProtoStringLiteral("bat")),
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_UNDEFINED"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_UNDEFINED"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_VALONE"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_VALONE"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_VALTWO"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_VALTWO"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
],
),
- ProtoMessage(None, ProtoIdentifier(None, "NestedMessage"), []),
- ProtoReserved(None, fields=[ProtoIdentifier(None, "a")]),
+ ProtoMessage(ProtoIdentifier("NestedMessage"), []),
+ ProtoReserved(fields=[ProtoIdentifier("a")]),
ProtoReserved(
- None,
ranges=[
ProtoRange(
- None,
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
)
],
),
- ProtoSingleLineComment(None, " single-line comment"),
+ ProtoSingleLineComment(" single-line comment"),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "some_field"),
- ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("some_field"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
True,
False,
None,
[
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "(bar.baz).bat"),
- ProtoConstant(None, ProtoStringLiteral(None, "bat")),
+ ProtoIdentifier("(bar.baz).bat"),
+ ProtoConstant(ProtoStringLiteral("bat")),
),
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "baz.bat"),
- ProtoConstant(
- None, ProtoInt(None, 100, ProtoIntSign.NEGATIVE)
- ),
+ ProtoIdentifier("baz.bat"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
),
],
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.BOOL,
- ProtoIdentifier(None, "some_bool_field"),
- ProtoInt(None, 5, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("some_bool_field"),
+ ProtoInt(5, ProtoIntSign.POSITIVE),
),
ProtoOneOf(
- None,
- ProtoIdentifier(None, "one_of_field"),
+ ProtoIdentifier("one_of_field"),
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "name"),
- ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(
- None, ProtoStringLiteral(None, "com.example.foo")
- ),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "sub_message"),
- ProtoInt(None, 9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("sub_message"),
+ ProtoInt(9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier(None, "SubMessage"),
+ ProtoFullIdentifier("SubMessage"),
[
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "(bar.baz).bat"),
- ProtoConstant(
- None, ProtoStringLiteral(None, "bat")
- ),
+ ProtoIdentifier("(bar.baz).bat"),
+ ProtoConstant(ProtoStringLiteral("bat")),
),
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "baz.bat"),
- ProtoConstant(
- None, ProtoInt(None, 100, ProtoIntSign.NEGATIVE)
- ),
+ ProtoIdentifier("baz.bat"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
),
],
),
],
),
ProtoMap(
- None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "my_map"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ ProtoIdentifier("my_map"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier("NestedMessage"),
[],
),
ProtoMap(
- None,
# map string_map = 11 [ java_package = "com.example.foo", baz.bat = 48 ];
ProtoMapKeyTypesEnum.STRING,
ProtoMapValueTypesEnum.STRING,
- ProtoIdentifier(None, "string_map"),
- ProtoInt(None, 11, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("string_map"),
+ ProtoInt(11, ProtoIntSign.POSITIVE),
None,
[
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(
- None, ProtoStringLiteral(None, "com.example.foo")
- ),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
),
ProtoMessageFieldOption(
- None,
- ProtoFullIdentifier(None, "baz.bat"),
- ProtoConstant(
- None, ProtoInt(None, 48, ProtoIntSign.POSITIVE)
- ),
+ ProtoFullIdentifier("baz.bat"),
+ ProtoConstant(ProtoInt(48, ProtoIntSign.POSITIVE)),
),
],
),
- ProtoExtensions(None, [ProtoRange(None, 8, ProtoRangeEnum.MAX)]),
+ ProtoExtensions([ProtoRange(8, ProtoRangeEnum.MAX)]),
],
)
self.assertEqual(
@@ -248,14 +214,11 @@ def test_message_all_features(self):
)
def test_empty_message(self):
- parsed_empty_message = ProtoMessage.match(None, """message FooMessage {}""")
+ parsed_empty_message = ProtoMessage.match("""message FooMessage {}""")
self.assertIsNotNone(parsed_empty_message)
- self.assertEqual(
- parsed_empty_message.node.name, ProtoIdentifier(None, "FooMessage")
- )
+ self.assertEqual(parsed_empty_message.node.name, ProtoIdentifier("FooMessage"))
parsed_spaced_message = ProtoMessage.match(
- None,
dedent(
"""
message FooMessage {
@@ -265,13 +228,10 @@ def test_empty_message(self):
),
)
self.assertIsNotNone(parsed_spaced_message)
- self.assertEqual(
- parsed_spaced_message.node.name, ProtoIdentifier(None, "FooMessage")
- )
+ self.assertEqual(parsed_spaced_message.node.name, ProtoIdentifier("FooMessage"))
def test_message_empty_statements(self):
empty_statement_message = ProtoMessage.match(
- None,
dedent(
"""
message FooMessage {
@@ -283,12 +243,11 @@ def test_message_empty_statements(self):
)
self.assertIsNotNone(empty_statement_message)
self.assertEqual(
- empty_statement_message.node.name, ProtoIdentifier(None, "FooMessage")
+ empty_statement_message.node.name, ProtoIdentifier("FooMessage")
)
def test_message_optionals(self):
parsed_message_with_optionals = ProtoMessage.match(
- None,
dedent(
"""
message FooMessage {
@@ -302,24 +261,21 @@ def test_message_optionals(self):
parsed_message_with_optionals.node.options,
[
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foobar")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foobar")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "(foo.bar).baz"),
- ProtoConstant(None, ProtoBool(None, False)),
+ ProtoIdentifier("(foo.bar).baz"),
+ ProtoConstant(ProtoBool(False)),
),
],
)
self.assertEqual(
- parsed_message_with_optionals.node.name, ProtoIdentifier(None, "FooMessage")
+ parsed_message_with_optionals.node.name, ProtoIdentifier("FooMessage")
)
def test_message_nested_enum(self):
parsed_message_with_enum = ProtoMessage.match(
- None,
dedent(
"""
message FooMessage {
@@ -335,27 +291,22 @@ def test_message_nested_enum(self):
self.assertEqual(
parsed_message_with_enum.node,
ProtoMessage(
- None,
- ProtoIdentifier(None, "FooMessage"),
+ ProtoIdentifier("FooMessage"),
[
ProtoEnum(
- None,
- ProtoIdentifier(None, "MyEnum"),
+ ProtoIdentifier("MyEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_UNDEFINED"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_UNDEFINED"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_NEGATIVE"),
- ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
+ ProtoIdentifier("ME_NEGATIVE"),
+ ProtoInt(1, ProtoIntSign.NEGATIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "ME_VALONE"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("ME_VALONE"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
],
)
@@ -365,7 +316,6 @@ def test_message_nested_enum(self):
def test_message_nested_message(self):
parsed_message_with_enum = ProtoMessage.match(
- None,
dedent(
"""
message FooMessage {
@@ -377,17 +327,15 @@ def test_message_nested_message(self):
self.assertEqual(
parsed_message_with_enum.node,
ProtoMessage(
- None,
- ProtoIdentifier(None, "FooMessage"),
+ ProtoIdentifier("FooMessage"),
[
- ProtoMessage(None, ProtoIdentifier(None, "NestedMessage"), []),
+ ProtoMessage(ProtoIdentifier("NestedMessage"), []),
],
),
)
def test_message_reserved_single_field(self):
parsed_message_with_reserved_single_field = ProtoMessage.match(
- None,
dedent(
"""
message FooMessage {
@@ -400,30 +348,25 @@ def test_message_reserved_single_field(self):
self.assertEqual(
parsed_message_with_reserved_single_field.node,
ProtoMessage(
- None,
- ProtoIdentifier(None, "FooMessage"),
+ ProtoIdentifier("FooMessage"),
[
ProtoReserved(
- None,
ranges=[
- ProtoRange(None, ProtoInt(None, 38, ProtoIntSign.POSITIVE)),
+ ProtoRange(ProtoInt(38, ProtoIntSign.POSITIVE)),
ProtoRange(
- None,
- ProtoInt(None, 48, ProtoIntSign.POSITIVE),
- ProtoInt(None, 100, ProtoIntSign.POSITIVE),
+ ProtoInt(48, ProtoIntSign.POSITIVE),
+ ProtoInt(100, ProtoIntSign.POSITIVE),
),
ProtoRange(
- None,
- ProtoInt(None, 72, ProtoIntSign.POSITIVE),
+ ProtoInt(72, ProtoIntSign.POSITIVE),
ProtoRangeEnum.MAX,
),
],
),
ProtoReserved(
- None,
fields=[
- ProtoIdentifier(None, "foo"),
- ProtoIdentifier(None, "barBaz"),
+ ProtoIdentifier("foo"),
+ ProtoIdentifier("barBaz"),
],
),
],
@@ -432,7 +375,6 @@ def test_message_reserved_single_field(self):
def test_message_simple_field(self):
parsed_message_with_single_field_simple = ProtoMessage.match(
- None,
dedent(
"""
message FooMessage {
@@ -444,35 +386,29 @@ def test_message_simple_field(self):
self.assertEqual(
parsed_message_with_single_field_simple.node,
ProtoMessage(
- None,
- ProtoIdentifier(None, "FooMessage"),
+ ProtoIdentifier("FooMessage"),
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "single_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("single_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
)
],
),
)
def test_oneof_empty(self):
- parsed_oneof_empty = ProtoOneOf.match(
- None, dedent("oneof one_of_field {}".strip())
- )
+ parsed_oneof_empty = ProtoOneOf.match(dedent("oneof one_of_field {}".strip()))
self.assertEqual(
parsed_oneof_empty.node,
ProtoOneOf(
- None,
- ProtoIdentifier(None, "one_of_field"),
+ ProtoIdentifier("one_of_field"),
[],
),
)
def test_oneof_empty_statements(self):
parsed_oneof_empty = ProtoOneOf.match(
- None,
dedent(
"""oneof one_of_field {
;
@@ -483,15 +419,13 @@ def test_oneof_empty_statements(self):
self.assertEqual(
parsed_oneof_empty.node,
ProtoOneOf(
- None,
- ProtoIdentifier(None, "one_of_field"),
+ ProtoIdentifier("one_of_field"),
[],
),
)
def test_oneof_basic_fields(self):
parsed_oneof_basic_fields = ProtoOneOf.match(
- None,
dedent(
"""oneof one_of_field {
string name = 4;
@@ -502,23 +436,20 @@ def test_oneof_basic_fields(self):
self.assertEqual(
parsed_oneof_basic_fields.node,
ProtoOneOf(
- None,
- ProtoIdentifier(None, "one_of_field"),
+ ProtoIdentifier("one_of_field"),
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "name"),
- ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "sub_message"),
- ProtoInt(None, 9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("sub_message"),
+ ProtoInt(9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier(None, "SubMessage"),
+ ProtoFullIdentifier("SubMessage"),
[],
),
],
@@ -527,7 +458,6 @@ def test_oneof_basic_fields(self):
def test_oneof_options(self):
parsed_oneof_options = ProtoOneOf.match(
- None,
dedent(
"""oneof one_of_field {
option java_package = "com.example.foo";
@@ -537,15 +467,11 @@ def test_oneof_options(self):
self.assertEqual(
parsed_oneof_options.node,
ProtoOneOf(
- None,
- ProtoIdentifier(None, "one_of_field"),
+ ProtoIdentifier("one_of_field"),
[
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(
- None, ProtoStringLiteral(None, "com.example.foo")
- ),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
),
],
),
@@ -553,7 +479,6 @@ def test_oneof_options(self):
def test_oneof_field_option(self):
parsed_oneof_field_option = ProtoOneOf.match(
- None,
dedent(
"""oneof one_of_field {
string name = 4 [ (bar.baz).bat = "bat", baz.bat = -100 ];
@@ -563,29 +488,23 @@ def test_oneof_field_option(self):
self.assertEqual(
parsed_oneof_field_option.node,
ProtoOneOf(
- None,
- ProtoIdentifier(None, "one_of_field"),
+ ProtoIdentifier("one_of_field"),
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "name"),
- ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
False,
False,
None,
[
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "(bar.baz).bat"),
- ProtoConstant(None, ProtoStringLiteral(None, "bat")),
+ ProtoIdentifier("(bar.baz).bat"),
+ ProtoConstant(ProtoStringLiteral("bat")),
),
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "baz.bat"),
- ProtoConstant(
- None, ProtoInt(None, 100, ProtoIntSign.NEGATIVE)
- ),
+ ProtoIdentifier("baz.bat"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
),
],
)
@@ -595,7 +514,6 @@ def test_oneof_field_option(self):
def test_oneof_with_comment(self):
parsed_oneof_with_comment = ProtoOneOf.match(
- None,
dedent(
"""oneof one_of_field {
string name = 4;
@@ -607,24 +525,21 @@ def test_oneof_with_comment(self):
self.assertEqual(
parsed_oneof_with_comment.node,
ProtoOneOf(
- None,
- ProtoIdentifier(None, "one_of_field"),
+ ProtoIdentifier("one_of_field"),
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "name"),
- ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
),
- ProtoSingleLineComment(None, " single-line comment!"),
+ ProtoSingleLineComment(" single-line comment!"),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "sub_message"),
- ProtoInt(None, 9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("sub_message"),
+ ProtoInt(9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier(None, "SubMessage"),
+ ProtoFullIdentifier("SubMessage"),
[],
),
],
@@ -633,7 +548,6 @@ def test_oneof_with_comment(self):
def test_oneof_normalize_removes_comment(self):
normalized_oneof = ProtoOneOf.match(
- None,
dedent(
"""oneof one_of_field {
string name = 4;
@@ -646,103 +560,89 @@ def test_oneof_normalize_removes_comment(self):
normalized_oneof.nodes,
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "name"),
- ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "sub_message"),
- ProtoInt(None, 9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("sub_message"),
+ ProtoInt(9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier(None, "SubMessage"),
+ ProtoFullIdentifier("SubMessage"),
[],
),
],
)
def test_simple_map(self):
- parsed_map_simple = ProtoMap.match(
- None, "map my_map = 10;"
- )
+ parsed_map_simple = ProtoMap.match("map my_map = 10;")
self.assertEqual(
parsed_map_simple.node,
ProtoMap(
- None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "my_map"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ ProtoIdentifier("my_map"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier("NestedMessage"),
[],
),
)
def test_map_without_spaces(self):
- map_without_spaces = ProtoMap.match(
- None, "map my_map = 10;"
- )
+ map_without_spaces = ProtoMap.match("map my_map = 10;")
self.assertEqual(
map_without_spaces.node,
ProtoMap(
- None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "my_map"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ ProtoIdentifier("my_map"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier("NestedMessage"),
[],
),
)
def test_map_with_options(self):
parsed_map_simple = ProtoMap.match(
- None,
"map my_map = 10 [ java_package = 'com.example.foo', baz.bat = 48 ];",
)
self.assertEqual(parsed_map_simple.node.key_type, ProtoMapKeyTypesEnum.SFIXED64)
self.assertEqual(
parsed_map_simple.node.value_type, ProtoMapValueTypesEnum.ENUM_OR_MESSAGE
)
- self.assertEqual(parsed_map_simple.node.name, ProtoIdentifier(None, "my_map"))
+ self.assertEqual(parsed_map_simple.node.name, ProtoIdentifier("my_map"))
self.assertEqual(
- parsed_map_simple.node.number, ProtoInt(None, 10, ProtoIntSign.POSITIVE)
+ parsed_map_simple.node.number, ProtoInt(10, ProtoIntSign.POSITIVE)
)
self.assertEqual(
parsed_map_simple.node.enum_or_message_type_name,
- ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ ProtoEnumOrMessageIdentifier("NestedMessage"),
)
self.assertEqual(
parsed_map_simple.node.options,
[
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "com.example.foo")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
),
ProtoMessageFieldOption(
- None,
- ProtoFullIdentifier(None, "baz.bat"),
- ProtoConstant(None, ProtoInt(None, 48, ProtoIntSign.POSITIVE)),
+ ProtoFullIdentifier("baz.bat"),
+ ProtoConstant(ProtoInt(48, ProtoIntSign.POSITIVE)),
),
],
)
def test_map_message_value(self):
- parsed_map_simple = ProtoMap.match(
- None, "map string_map = 11;"
- )
+ parsed_map_simple = ProtoMap.match("map string_map = 11;")
self.assertEqual(
parsed_map_simple.node,
ProtoMap(
- None,
ProtoMapKeyTypesEnum.STRING,
ProtoMapValueTypesEnum.STRING,
- ProtoIdentifier(None, "string_map"),
- ProtoInt(None, 11, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("string_map"),
+ ProtoInt(11, ProtoIntSign.POSITIVE),
None,
[],
),
@@ -750,7 +650,6 @@ def test_map_message_value(self):
def test_message_parses_comments(self):
parsed_comments = ProtoMessage.match(
- None,
dedent(
"""
message MyMessage {
@@ -771,34 +670,29 @@ def test_message_parses_comments(self):
parsed_comments.node.nodes,
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
- ProtoSingleLineComment(None, " single-line comment!"),
+ ProtoSingleLineComment(" single-line comment!"),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.BOOL,
- ProtoIdentifier(None, "bar"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
ProtoMultiLineComment(
- None,
"\n multiple\n line\n comment!\n ",
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "baz"),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("baz"),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
),
],
)
def test_message_extends(self):
parsed_extends = ProtoMessage.match(
- None,
dedent(
"""
message MyMessage {
@@ -814,20 +708,17 @@ def test_message_extends(self):
parsed_extends.node.nodes,
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoExtend(
- None,
- ProtoEnumOrMessageIdentifier(None, "SomeOtherMessage"),
+ ProtoEnumOrMessageIdentifier("SomeOtherMessage"),
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
)
],
),
@@ -836,7 +727,6 @@ def test_message_extends(self):
def test_message_normalizes_away_comments(self):
parsed_comments = ProtoMessage.match(
- None,
dedent(
"""
message MyMessage {
@@ -857,73 +747,62 @@ def test_message_normalizes_away_comments(self):
parsed_comments.nodes,
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "foo"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("foo"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.BOOL,
- ProtoIdentifier(None, "bar"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("bar"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "baz"),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("baz"),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
),
],
)
def test_diff_same_message_returns_empty(self):
pm1 = ProtoMessage(
- None,
- ProtoIdentifier(None, "MyMessage"),
+ ProtoIdentifier("MyMessage"),
[],
)
pm2 = ProtoMessage(
- None,
- ProtoIdentifier(None, "MyMessage"),
+ ProtoIdentifier("MyMessage"),
[],
)
self.assertEqual(ProtoMessage.diff(pm1, pm2), [])
def test_diff_different_message_name_returns_empty(self):
pm1 = ProtoMessage(
- None,
- ProtoIdentifier(None, "MyMessage"),
+ ProtoIdentifier("MyMessage"),
[],
)
pm2 = ProtoMessage(
- None,
- ProtoIdentifier(None, "OtherMessage"),
+ ProtoIdentifier("OtherMessage"),
[],
)
self.assertEqual(ProtoMessage.diff(pm1, pm2), [])
def test_diff_enum_added(self):
pm1 = None
- pm2 = ProtoMessage(None, ProtoIdentifier(None, "MyMessage"), [])
+ pm2 = ProtoMessage(ProtoIdentifier("MyMessage"), [])
self.assertEqual(
ProtoMessage.diff(pm1, pm2),
[
- ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "MyMessage"), [])
- ),
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("MyMessage"), [])),
],
)
def test_diff_message_removed(self):
- pm1 = ProtoMessage(None, ProtoIdentifier(None, "MyMessage"), [])
+ pm1 = ProtoMessage(ProtoIdentifier("MyMessage"), [])
pm2 = None
self.assertEqual(
ProtoMessage.diff(pm1, pm2),
[
- ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "MyMessage"), [])
- ),
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("MyMessage"), [])),
],
)
@@ -934,36 +813,30 @@ def test_diff_sets_empty_returns_empty(self):
def test_diff_sets_no_change_returns_empty(self):
set1 = [
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
]
self.assertEqual(ProtoMessage.diff_sets(set1, set1), [])
def test_diff_sets_all_removed(self):
set1 = [
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
]
set2 = []
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
- ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
- ),
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage"), [])),
diff,
)
self.assertIn(
- ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), [])
- ),
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BarMessage"), [])),
diff,
)
self.assertIn(
- ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
- ),
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage"), [])),
diff,
)
self.assertEqual(3, len(diff))
@@ -971,78 +844,60 @@ def test_diff_sets_all_removed(self):
def test_diff_sets_all_added(self):
set1 = []
set2 = [
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
]
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
- ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
- ),
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage"), [])),
diff,
)
self.assertIn(
- ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), [])
- ),
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BarMessage"), [])),
diff,
)
self.assertIn(
- ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
- ),
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage"), [])),
diff,
)
self.assertEqual(3, len(diff))
def test_diff_sets_mutually_exclusive(self):
set1 = [
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
]
set2 = [
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage2"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), []),
+ ProtoMessage(ProtoIdentifier("FooMessage2"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage2"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage2"), []),
]
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
- ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), [])
- ),
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage2"), [])),
diff,
)
self.assertIn(
- ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage2"), [])
- ),
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BarMessage2"), [])),
diff,
)
self.assertIn(
- ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), [])
- ),
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage2"), [])),
diff,
)
self.assertIn(
- ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
- ),
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage"), [])),
diff,
)
self.assertIn(
- ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), [])
- ),
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BarMessage"), [])),
diff,
)
self.assertIn(
- ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
- ),
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage"), [])),
diff,
)
self.assertEqual(6, len(diff))
@@ -1050,38 +905,30 @@ def test_diff_sets_mutually_exclusive(self):
def test_diff_sets_overlap(self):
set1 = [
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), []),
+ ProtoMessage(ProtoIdentifier("FooMessage"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage"), []),
]
set2 = [
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BarMessage"), []),
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), []),
+ ProtoMessage(ProtoIdentifier("FooMessage2"), []),
+ ProtoMessage(ProtoIdentifier("BarMessage"), []),
+ ProtoMessage(ProtoIdentifier("BazMessage2"), []),
]
diff = ProtoMessage.diff_sets(set1, set2)
self.assertIn(
- ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage2"), [])
- ),
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage2"), [])),
diff,
)
self.assertIn(
- ProtoMessageAdded(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage2"), [])
- ),
+ ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage2"), [])),
diff,
)
self.assertIn(
- ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "FooMessage"), [])
- ),
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage"), [])),
diff,
)
self.assertIn(
- ProtoMessageRemoved(
- ProtoMessage(None, ProtoIdentifier(None, "BazMessage"), [])
- ),
+ ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage"), [])),
diff,
)
self.assertEqual(4, len(diff))
diff --git a/test/proto_option_test.py b/test/proto_option_test.py
index b4f52fc..b6a90a2 100644
--- a/test/proto_option_test.py
+++ b/test/proto_option_test.py
@@ -19,245 +19,231 @@ class OptionTest(unittest.TestCase):
maxDiff = None
def test_string_option(self):
- string_option = ProtoOption.match(None, "option foo = 'test value';")
- self.assertEqual(string_option.node.name, ProtoIdentifier(None, "foo"))
+ string_option = ProtoOption.match("option foo = 'test value';")
+ self.assertEqual(string_option.node.name, ProtoIdentifier("foo"))
self.assertEqual(
- string_option.node.value.value, ProtoStringLiteral(None, "test value")
+ string_option.node.value.value, ProtoStringLiteral("test value")
)
self.assertEqual(string_option.remaining_source, "")
- string_option = ProtoOption.match(None, 'option foo = "test value";')
- self.assertEqual(string_option.node.name, ProtoIdentifier(None, "foo"))
+ string_option = ProtoOption.match('option foo = "test value";')
+ self.assertEqual(string_option.node.name, ProtoIdentifier("foo"))
self.assertEqual(
- string_option.node.value.value, ProtoStringLiteral(None, "test value")
+ string_option.node.value.value, ProtoStringLiteral("test value")
)
self.assertEqual(string_option.remaining_source, "")
def test_packaged_name(self):
- packaged_option = ProtoOption.match(None, "option foo.bar.baz = 'test value';")
+ packaged_option = ProtoOption.match("option foo.bar.baz = 'test value';")
+ self.assertEqual(packaged_option.node.name, ProtoFullIdentifier("foo.bar.baz"))
self.assertEqual(
- packaged_option.node.name, ProtoFullIdentifier(None, "foo.bar.baz")
- )
- self.assertEqual(
- packaged_option.node.value.value, ProtoStringLiteral(None, "test value")
+ packaged_option.node.value.value, ProtoStringLiteral("test value")
)
def test_parenthesized_name(self):
- parenthesized_option = ProtoOption.match(None, "option (foo) = 'test value';")
- self.assertEqual(parenthesized_option.node.name, ProtoIdentifier(None, "(foo)"))
+ parenthesized_option = ProtoOption.match("option (foo) = 'test value';")
+ self.assertEqual(parenthesized_option.node.name, ProtoIdentifier("(foo)"))
self.assertEqual(
parenthesized_option.node.value.value,
- ProtoStringLiteral(None, "test value"),
+ ProtoStringLiteral("test value"),
)
fully_qualified_name_option = ProtoOption.match(
- None, "option (foo).bar.baz = 'test value';"
+ "option (foo).bar.baz = 'test value';"
)
self.assertEqual(
fully_qualified_name_option.node.name,
- ProtoFullIdentifier(None, "(foo).bar.baz"),
+ ProtoFullIdentifier("(foo).bar.baz"),
)
self.assertEqual(
fully_qualified_name_option.node.value.value,
- ProtoStringLiteral(None, "test value"),
+ ProtoStringLiteral("test value"),
)
def test_string_option_missing_semicolon(self):
with self.assertRaises(ValueError):
- ProtoOption.match(None, "option foo = 'test value'")
+ ProtoOption.match("option foo = 'test value'")
with self.assertRaises(ValueError):
- ProtoOption.match(None, 'option foo = "test value"')
+ ProtoOption.match('option foo = "test value"')
def test_string_option_missing_quote(self):
with self.assertRaises(ValueError):
- ProtoOption.match(None, "option foo = test value;")
+ ProtoOption.match("option foo = test value;")
with self.assertRaises(ValueError):
- ProtoOption.match(None, "option foo = 'test value;")
+ ProtoOption.match("option foo = 'test value;")
with self.assertRaises(ValueError):
- ProtoOption.match(None, 'option foo = "test value;')
+ ProtoOption.match('option foo = "test value;')
with self.assertRaises(ValueError):
- ProtoOption.match(None, "option foo = test value';")
+ ProtoOption.match("option foo = test value';")
with self.assertRaises(ValueError):
- ProtoOption.match(None, 'option foo = test value";')
+ ProtoOption.match('option foo = test value";')
with self.assertRaises(ValueError):
- ProtoOption.match(None, "option foo = 'test value\";")
+ ProtoOption.match("option foo = 'test value\";")
with self.assertRaises(ValueError):
- ProtoOption.match(None, "option foo = \"test value';")
+ ProtoOption.match("option foo = \"test value';")
def test_identifier_option(self):
- identifier_option = ProtoOption.match(None, "option foo = test_identifier;")
- self.assertEqual(identifier_option.node.name, ProtoIdentifier(None, "foo"))
+ identifier_option = ProtoOption.match("option foo = test_identifier;")
+ self.assertEqual(identifier_option.node.name, ProtoIdentifier("foo"))
self.assertEqual(
identifier_option.node.value,
- ProtoConstant(None, ProtoIdentifier(None, "test_identifier")),
+ ProtoConstant(ProtoIdentifier("test_identifier")),
)
self.assertEqual(identifier_option.remaining_source, "")
- identifier_option = ProtoOption.match(None, "option bar = foo.bar.baz;")
- self.assertEqual(identifier_option.node.name, ProtoIdentifier(None, "bar"))
+ identifier_option = ProtoOption.match("option bar = foo.bar.baz;")
+ self.assertEqual(identifier_option.node.name, ProtoIdentifier("bar"))
self.assertEqual(
identifier_option.node.value,
- ProtoConstant(None, ProtoFullIdentifier(None, "foo.bar.baz")),
+ ProtoConstant(ProtoFullIdentifier("foo.bar.baz")),
)
self.assertEqual(identifier_option.remaining_source, "")
def test_int_option(self):
- int_option = ProtoOption.match(None, "option foo = 0;")
- self.assertEqual(int_option.node.name, ProtoIdentifier(None, "foo"))
+ int_option = ProtoOption.match("option foo = 0;")
+ self.assertEqual(int_option.node.name, ProtoIdentifier("foo"))
self.assertEqual(
int_option.node.value,
- ProtoConstant(None, ProtoInt(None, 0, ProtoIntSign.POSITIVE)),
+ ProtoConstant(ProtoInt(0, ProtoIntSign.POSITIVE)),
)
self.assertEqual(int_option.remaining_source, "")
- int_option = ProtoOption.match(None, "option foo = 12345;")
- self.assertEqual(int_option.node.name, ProtoIdentifier(None, "foo"))
+ int_option = ProtoOption.match("option foo = 12345;")
+ self.assertEqual(int_option.node.name, ProtoIdentifier("foo"))
self.assertEqual(
int_option.node.value,
- ProtoConstant(None, ProtoInt(None, 12345, ProtoIntSign.POSITIVE)),
+ ProtoConstant(ProtoInt(12345, ProtoIntSign.POSITIVE)),
)
self.assertEqual(int_option.remaining_source, "")
- int_option = ProtoOption.match(None, "option foo = +42;")
- self.assertEqual(int_option.node.name, ProtoIdentifier(None, "foo"))
+ int_option = ProtoOption.match("option foo = +42;")
+ self.assertEqual(int_option.node.name, ProtoIdentifier("foo"))
self.assertEqual(
int_option.node.value,
- ProtoConstant(None, ProtoInt(None, 42, ProtoIntSign.POSITIVE)),
+ ProtoConstant(ProtoInt(42, ProtoIntSign.POSITIVE)),
)
self.assertEqual(int_option.remaining_source, "")
- int_option = ProtoOption.match(None, "option foo = -12;")
- self.assertEqual(int_option.node.name, ProtoIdentifier(None, "foo"))
+ int_option = ProtoOption.match("option foo = -12;")
+ self.assertEqual(int_option.node.name, ProtoIdentifier("foo"))
self.assertEqual(
int_option.node.value,
- ProtoConstant(None, ProtoInt(None, 12, ProtoIntSign.NEGATIVE)),
+ ProtoConstant(ProtoInt(12, ProtoIntSign.NEGATIVE)),
)
self.assertEqual(int_option.remaining_source, "")
def test_float_option(self):
- float_option = ProtoOption.match(None, "option foo = inf;")
+ float_option = ProtoOption.match("option foo = inf;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(
- None, ProtoFloat(None, float("inf"), ProtoFloatSign.POSITIVE)
- ),
+ ProtoConstant(ProtoFloat(float("inf"), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match(None, "option foo = nan;")
+ float_option = ProtoOption.match("option foo = nan;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(
- None, ProtoFloat(None, float("nan"), ProtoFloatSign.POSITIVE)
- ),
+ ProtoConstant(ProtoFloat(float("nan"), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match(None, "option foo = 12.1;")
+ float_option = ProtoOption.match("option foo = 12.1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(None, ProtoFloat(None, float(12.1), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(ProtoFloat(float(12.1), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match(None, "option foo = .1;")
+ float_option = ProtoOption.match("option foo = .1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(None, ProtoFloat(None, float(0.1), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(ProtoFloat(float(0.1), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match(None, "option foo = .1e3;")
+ float_option = ProtoOption.match("option foo = .1e3;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(None, ProtoFloat(None, float(100), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(ProtoFloat(float(100), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match(None, "option foo = +12.1;")
+ float_option = ProtoOption.match("option foo = +12.1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(None, ProtoFloat(None, float(12.1), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(ProtoFloat(float(12.1), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match(None, "option foo = +.1;")
+ float_option = ProtoOption.match("option foo = +.1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(None, ProtoFloat(None, float(0.1), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(ProtoFloat(float(0.1), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match(None, "option foo = +.1e2;")
+ float_option = ProtoOption.match("option foo = +.1e2;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(None, ProtoFloat(None, float(10), ProtoFloatSign.POSITIVE)),
+ ProtoConstant(ProtoFloat(float(10), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match(None, "option foo = +.1e-2;")
+ float_option = ProtoOption.match("option foo = +.1e-2;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(
- None, ProtoFloat(None, float(0.001), ProtoFloatSign.POSITIVE)
- ),
+ ProtoConstant(ProtoFloat(float(0.001), ProtoFloatSign.POSITIVE)),
)
- float_option = ProtoOption.match(None, "option foo = -.1e0;")
+ float_option = ProtoOption.match("option foo = -.1e0;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(None, ProtoFloat(None, float(0.1), ProtoFloatSign.NEGATIVE)),
+ ProtoConstant(ProtoFloat(float(0.1), ProtoFloatSign.NEGATIVE)),
)
- float_option = ProtoOption.match(None, "option foo = -12E+1;")
+ float_option = ProtoOption.match("option foo = -12E+1;")
self.assertEqual(
float_option.node.value,
- ProtoConstant(None, ProtoFloat(None, float(120), ProtoFloatSign.NEGATIVE)),
+ ProtoConstant(ProtoFloat(float(120), ProtoFloatSign.NEGATIVE)),
)
def test_diff_same_option_returns_empty(self):
po1 = ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
po2 = ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
self.assertEqual(ProtoOption.diff(po1, po2), [])
def test_diff_different_option_name_returns_empty(self):
po1 = ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
po2 = ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
self.assertEqual(ProtoOption.diff(po1, po2), [])
def test_diff_different_option_value_returns_option_diff(self):
po1 = ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
po2 = ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "other value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("other value")),
)
self.assertEqual(
ProtoOption.diff(po1, po2),
[
ProtoOptionValueChanged(
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
- ProtoConstant(None, ProtoStringLiteral(None, "other value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
+ ProtoConstant(ProtoStringLiteral("other value")),
)
],
)
@@ -265,18 +251,16 @@ def test_diff_different_option_value_returns_option_diff(self):
def test_diff_option_added(self):
po1 = None
po2 = ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
self.assertEqual(
ProtoOption.diff(po1, po2),
[
ProtoOptionAdded(
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
),
],
@@ -284,9 +268,8 @@ def test_diff_option_added(self):
def test_diff_option_removed(self):
po1 = ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
po2 = None
self.assertEqual(
@@ -294,9 +277,8 @@ def test_diff_option_removed(self):
[
ProtoOptionRemoved(
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
),
],
@@ -310,19 +292,16 @@ def test_diff_sets_empty_returns_empty(self):
def test_diff_sets_no_change(self):
set1 = [
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
),
]
self.assertEqual(ProtoOption.diff_sets(set1, set1), [])
@@ -330,19 +309,16 @@ def test_diff_sets_no_change(self):
def test_diff_sets_all_removed(self):
set1 = [
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
),
]
set2 = []
@@ -351,9 +327,8 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
),
diff,
@@ -361,9 +336,8 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
)
),
diff,
@@ -371,9 +345,8 @@ def test_diff_sets_all_removed(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -384,19 +357,16 @@ def test_diff_sets_all_added(self):
set1 = []
set2 = [
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
),
]
diff = ProtoOption.diff_sets(set1, set2)
@@ -404,9 +374,8 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
),
diff,
@@ -414,9 +383,8 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
)
),
diff,
@@ -424,9 +392,8 @@ def test_diff_sets_all_added(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -436,36 +403,30 @@ def test_diff_sets_all_added(self):
def test_diff_sets_mutually_exclusive(self):
set1 = [
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
),
]
set2 = [
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option.but.not.prior"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option.but.not.prior"),
+ ProtoConstant(ProtoStringLiteral("some value")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "ruby_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("ruby_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option.but.stil.not.prior"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option.but.stil.not.prior"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
),
]
@@ -474,9 +435,8 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option.but.not.prior"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option.but.not.prior"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
),
diff,
@@ -484,9 +444,8 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option.but.stil.not.prior"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option.but.stil.not.prior"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -495,9 +454,8 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- None,
- ProtoIdentifier(None, "ruby_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("ruby_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
)
),
diff,
@@ -506,9 +464,8 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -517,9 +474,8 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
),
diff,
@@ -528,9 +484,8 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
)
),
diff,
@@ -541,36 +496,30 @@ def test_diff_sets_mutually_exclusive(self):
def test_diff_sets_overlap(self):
set1 = [
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
),
]
set2 = [
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option.but.not.prior"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option.but.not.prior"),
+ ProtoConstant(ProtoStringLiteral("some value")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.bat")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.bat")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option.but.stil.not.prior"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option.but.stil.not.prior"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
),
]
@@ -579,9 +528,8 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
),
diff,
@@ -590,9 +538,8 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoOptionRemoved(
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
)
),
diff,
@@ -600,9 +547,8 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- None,
- ProtoIdentifier(None, "some.custom.option.but.not.prior"),
- ProtoConstant(None, ProtoStringLiteral(None, "some value")),
+ ProtoIdentifier("some.custom.option.but.not.prior"),
+ ProtoConstant(ProtoStringLiteral("some value")),
)
),
diff,
@@ -610,18 +556,17 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoOptionAdded(
ProtoOption(
- None,
- ProtoIdentifier(None, "other.option.but.stil.not.prior"),
- ProtoConstant(None, ProtoInt(None, 100, ProtoIntSign.POSITIVE)),
+ ProtoIdentifier("other.option.but.stil.not.prior"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
)
),
diff,
)
self.assertIn(
ProtoOptionValueChanged(
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.baz")),
- ProtoConstant(None, ProtoStringLiteral(None, "foo.bar.bat")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
+ ProtoConstant(ProtoStringLiteral("foo.bar.bat")),
),
diff,
)
diff --git a/test/proto_package_test.py b/test/proto_package_test.py
index 611dd37..bf6bd7d 100644
--- a/test/proto_package_test.py
+++ b/test/proto_package_test.py
@@ -11,92 +11,90 @@
class PackageTest(unittest.TestCase):
def test_correct_package(self):
- self.assertEqual(ProtoPackage.match(None, "package foo;").node.package, "foo")
+ self.assertEqual(ProtoPackage.match("package foo;").node.package, "foo")
+ self.assertEqual(ProtoPackage.match("package foo.bar;").node.package, "foo.bar")
self.assertEqual(
- ProtoPackage.match(None, "package foo.bar;").node.package, "foo.bar"
- )
- self.assertEqual(
- ProtoPackage.match(None, "package foo.bar.baz;").node.package, "foo.bar.baz"
+ ProtoPackage.match("package foo.bar.baz;").node.package, "foo.bar.baz"
)
def test_package_serialize(self):
self.assertEqual(
- ProtoPackage.match(None, "package foo;").node.serialize(), "package foo;"
+ ProtoPackage.match("package foo;").node.serialize(), "package foo;"
)
self.assertEqual(
- ProtoPackage.match(None, "package foo.bar;").node.serialize(),
+ ProtoPackage.match("package foo.bar;").node.serialize(),
"package foo.bar;",
)
self.assertEqual(
- ProtoPackage.match(None, "package foo.bar.baz;").node.serialize(),
+ ProtoPackage.match("package foo.bar.baz;").node.serialize(),
"package foo.bar.baz;",
)
def test_package_malformed(self):
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "package")
+ ProtoPackage.match("package")
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "package;")
+ ProtoPackage.match("package;")
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "package ")
+ ProtoPackage.match("package ")
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "package ;")
+ ProtoPackage.match("package ;")
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "packagefoo")
+ ProtoPackage.match("packagefoo")
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "package foo.")
+ ProtoPackage.match("package foo.")
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "packagefoo.")
+ ProtoPackage.match("packagefoo.")
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "package foo.;")
+ ProtoPackage.match("package foo.;")
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "package foo.bar")
+ ProtoPackage.match("package foo.bar")
with self.assertRaises(ValueError):
- ProtoPackage.match(None, "packagefoo.bar;")
+ ProtoPackage.match("packagefoo.bar;")
def test_diff_same_package_returns_empty(self):
- pp1 = ProtoPackage(None, "my.awesome.package")
- pp2 = ProtoPackage(None, "my.awesome.package")
+ pp1 = ProtoPackage("my.awesome.package")
+ pp2 = ProtoPackage("my.awesome.package")
self.assertEqual(ProtoPackage.diff(pp1, pp2), [])
def test_diff_different_package_returns_package_diff(self):
- pp1 = ProtoPackage(None, "my.awesome.package")
- pp2 = ProtoPackage(None, "my.other.awesome.package")
+ pp1 = ProtoPackage("my.awesome.package")
+ pp2 = ProtoPackage("my.other.awesome.package")
self.assertEqual(
ProtoPackage.diff(pp1, pp2),
[
ProtoPackageChanged(
- ProtoPackage(None, "my.awesome.package"),
- ProtoPackage(None, "my.other.awesome.package"),
+ ProtoPackage("my.awesome.package"),
+ ProtoPackage("my.other.awesome.package"),
)
],
)
def test_diff_package_added(self):
pp1 = None
- pp2 = ProtoPackage(None, "my.new.package")
+ pp2 = ProtoPackage("my.new.package")
self.assertEqual(
[
- ProtoPackageAdded(ProtoPackage(None, "my.new.package")),
+ ProtoPackageAdded(ProtoPackage("my.new.package")),
],
ProtoPackage.diff(pp1, pp2),
)
def test_diff_package_removed(self):
- pp1 = ProtoPackage(None, "my.old.package")
+ pp1 = ProtoPackage("my.old.package")
pp2 = None
self.assertEqual(
[
- ProtoPackageRemoved(ProtoPackage(None, "my.old.package")),
+ ProtoPackageRemoved(ProtoPackage("my.old.package")),
],
ProtoPackage.diff(pp1, pp2),
)
diff --git a/test/proto_range_test.py b/test/proto_range_test.py
index 24f90a5..ce78433 100644
--- a/test/proto_range_test.py
+++ b/test/proto_range_test.py
@@ -5,42 +5,38 @@
class RangeTest(unittest.TestCase):
def test_range_single_int(self):
- self.assertEqual(ProtoRange.match(None, "42").node.serialize(), "42")
- self.assertEqual(ProtoRange.match(None, "-1").node.serialize(), "-1")
+ self.assertEqual(ProtoRange.match("42").node.serialize(), "42")
+ self.assertEqual(ProtoRange.match("-1").node.serialize(), "-1")
def test_range_invalid_non_ints(self):
- self.assertIsNone(ProtoRange.match(None, "42.5"))
- self.assertIsNone(ProtoRange.match(None, "a"))
- self.assertIsNone(ProtoRange.match(None, "-"))
+ self.assertIsNone(ProtoRange.match("42.5"))
+ self.assertIsNone(ProtoRange.match("a"))
+ self.assertIsNone(ProtoRange.match("-"))
def test_range_int_range(self):
- self.assertEqual(ProtoRange.match(None, "1 to 1").node.serialize(), "1 to 1")
- self.assertEqual(ProtoRange.match(None, "1 to 7").node.serialize(), "1 to 7")
- self.assertEqual(
- ProtoRange.match(None, "-100 to -5").node.serialize(), "-100 to -5"
- )
+ self.assertEqual(ProtoRange.match("1 to 1").node.serialize(), "1 to 1")
+ self.assertEqual(ProtoRange.match("1 to 7").node.serialize(), "1 to 7")
+ self.assertEqual(ProtoRange.match("-100 to -5").node.serialize(), "-100 to -5")
def test_range_invalid_range(self):
with self.assertRaises(ValueError):
- ProtoRange.match(None, "8 to 2")
+ ProtoRange.match("8 to 2")
with self.assertRaises(ValueError):
- ProtoRange.match(None, "3 to 0")
+ ProtoRange.match("3 to 0")
with self.assertRaises(ValueError):
- ProtoRange.match(None, "1 to -1")
+ ProtoRange.match("1 to -1")
def test_range_invalid_range_non_int(self):
with self.assertRaises(ValueError):
- ProtoRange.match(None, "1 to c")
+ ProtoRange.match("1 to c")
with self.assertRaises(ValueError):
- ProtoRange.match(None, "1 to -bc3")
+ ProtoRange.match("1 to -bc3")
def test_range_max(self):
- self.assertEqual(
- ProtoRange.match(None, "7 to max").node.serialize(), "7 to max"
- )
+ self.assertEqual(ProtoRange.match("7 to max").node.serialize(), "7 to max")
if __name__ == "__main__":
diff --git a/test/proto_reserved_test.py b/test/proto_reserved_test.py
index f7d1c8b..e83aca8 100644
--- a/test/proto_reserved_test.py
+++ b/test/proto_reserved_test.py
@@ -7,47 +7,47 @@
class ReservedTest(unittest.TestCase):
def test_reserved_single_int(self):
self.assertEqual(
- ProtoReserved.match(None, "reserved 21;").node.serialize(), "reserved 21;"
+ ProtoReserved.match("reserved 21;").node.serialize(), "reserved 21;"
)
self.assertEqual(
- ProtoReserved.match(None, "reserved -1;").node.serialize(), "reserved -1;"
+ ProtoReserved.match("reserved -1;").node.serialize(), "reserved -1;"
)
def test_reserved_multiple_ints(self):
self.assertEqual(
- ProtoReserved.match(None, "reserved 1, 5, 2, 42;").node.serialize(),
+ ProtoReserved.match("reserved 1, 5, 2, 42;").node.serialize(),
"reserved 1, 5, 2, 42;",
)
def test_reserved_range_max(self):
self.assertEqual(
- ProtoReserved.match(None, "reserved 8 to max;").node.serialize(),
+ ProtoReserved.match("reserved 8 to max;").node.serialize(),
"reserved 8 to max;",
)
def test_reserved_single_string_field(self):
self.assertEqual(
- ProtoReserved.match(None, "reserved 'foo';").node.serialize(),
+ ProtoReserved.match("reserved 'foo';").node.serialize(),
"reserved 'foo';",
)
self.assertEqual(
- ProtoReserved.match(None, 'reserved "foo";').node.serialize(),
+ ProtoReserved.match('reserved "foo";').node.serialize(),
'reserved "foo";',
)
def test_reserved_multiple_string_fields(self):
self.assertEqual(
- ProtoReserved.match(None, "reserved 'foo', 'bar';").node.serialize(),
+ ProtoReserved.match("reserved 'foo', 'bar';").node.serialize(),
"reserved 'foo', 'bar';",
)
self.assertEqual(
- ProtoReserved.match(None, 'reserved "foo", "bar", "baz";').node.serialize(),
+ ProtoReserved.match('reserved "foo", "bar", "baz";').node.serialize(),
'reserved "foo", "bar", "baz";',
)
def test_reserved_cannot_have_ints_and_strings(self):
with self.assertRaises(ValueError):
- ProtoReserved.match(None, "reserved 1, 'foo';")
+ ProtoReserved.match("reserved 1, 'foo';")
if __name__ == "__main__":
diff --git a/test/proto_service_test.py b/test/proto_service_test.py
index b99a242..0b5a4fb 100644
--- a/test/proto_service_test.py
+++ b/test/proto_service_test.py
@@ -20,7 +20,6 @@ class ServiceTest(unittest.TestCase):
def test_service_all_features(self):
test_service_all_features = ProtoService.match(
- None,
dedent(
"""
service FooService {
@@ -41,52 +40,42 @@ def test_service_all_features(self):
self.assertEqual(
test_service_all_features.node,
ProtoService(
- None,
- ProtoIdentifier(None, "FooService"),
+ ProtoIdentifier("FooService"),
[
ProtoOption(
- None,
- ProtoIdentifier(None, "(foo.bar).baz"),
- ProtoConstant(None, ProtoStringLiteral(None, "bat")),
+ ProtoIdentifier("(foo.bar).baz"),
+ ProtoConstant(ProtoStringLiteral("bat")),
),
- ProtoSingleLineComment(None, " single-line comment!"),
+ ProtoSingleLineComment(" single-line comment!"),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "OneRPC"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
+ ProtoIdentifier("OneRPC"),
+ ProtoEnumOrMessageIdentifier("OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier("OneRPCResponse"),
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "TwoRPC"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
+ ProtoIdentifier("TwoRPC"),
+ ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
False,
True,
),
ProtoMultiLineComment(
- None,
"\n multiple\n line\n comment\n ",
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "ThreeRPC"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
+ ProtoIdentifier("ThreeRPC"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
False,
False,
[
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(
- None, ProtoStringLiteral(None, "com.example.foo")
- ),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
),
ProtoOption(
- None,
- ProtoFullIdentifier(None, "(foo.bar).baz"),
- ProtoConstant(None, ProtoBool(None, False)),
+ ProtoFullIdentifier("(foo.bar).baz"),
+ ProtoConstant(ProtoBool(False)),
),
],
),
@@ -114,14 +103,11 @@ def test_service_all_features(self):
)
def test_service_empty(self):
- parsed_empty_service = ProtoService.match(None, """service FooService {}""")
+ parsed_empty_service = ProtoService.match("""service FooService {}""")
self.assertIsNotNone(parsed_empty_service)
- self.assertEqual(
- parsed_empty_service.node.name, ProtoIdentifier(None, "FooService")
- )
+ self.assertEqual(parsed_empty_service.node.name, ProtoIdentifier("FooService"))
parsed_spaced_service = ProtoService.match(
- None,
dedent(
"""
service FooService {
@@ -133,12 +119,11 @@ def test_service_empty(self):
self.assertIsNotNone(parsed_spaced_service)
self.assertEqual(
parsed_spaced_service.node,
- ProtoService(None, ProtoIdentifier(None, "FooService"), []),
+ ProtoService(ProtoIdentifier("FooService"), []),
)
def test_service_empty_statements(self):
empty_statement_service = ProtoService.match(
- None,
dedent(
"""
service FooService {
@@ -151,12 +136,11 @@ def test_service_empty_statements(self):
self.assertIsNotNone(empty_statement_service)
self.assertEqual(
empty_statement_service.node,
- ProtoService(None, ProtoIdentifier(None, "FooService"), []),
+ ProtoService(ProtoIdentifier("FooService"), []),
)
def test_service_option(self):
service_with_options = ProtoService.match(
- None,
dedent(
"""
service FooService {
@@ -169,16 +153,14 @@ def test_service_option(self):
service_with_options.node.nodes,
[
ProtoOption(
- None,
- ProtoIdentifier(None, "(foo.bar).baz"),
- ProtoConstant(None, ProtoStringLiteral(None, "bat")),
+ ProtoIdentifier("(foo.bar).baz"),
+ ProtoConstant(ProtoStringLiteral("bat")),
)
],
)
def test_service_rpc_basic(self):
service_with_options = ProtoService.match(
- None,
dedent(
"""
service FooService {
@@ -193,29 +175,25 @@ def test_service_rpc_basic(self):
service_with_options.node.nodes,
[
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "OneRPC"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
+ ProtoIdentifier("OneRPC"),
+ ProtoEnumOrMessageIdentifier("OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier("OneRPCResponse"),
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "TwoRPC"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
+ ProtoIdentifier("TwoRPC"),
+ ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "ThreeRPC"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
+ ProtoIdentifier("ThreeRPC"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
),
],
)
def test_service_rpc_stream(self):
service_with_options = ProtoService.match(
- None,
dedent(
"""
service FooService {
@@ -229,18 +207,16 @@ def test_service_rpc_stream(self):
service_with_options.node.nodes,
[
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "OneRPC"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
+ ProtoIdentifier("OneRPC"),
+ ProtoEnumOrMessageIdentifier("OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier("OneRPCResponse"),
True,
False,
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "TwoRPC"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
+ ProtoIdentifier("TwoRPC"),
+ ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
False,
True,
),
@@ -249,7 +225,6 @@ def test_service_rpc_stream(self):
def test_service_rpc_options(self):
service_with_options = ProtoService.match(
- None,
dedent(
"""
service FooService {
@@ -263,30 +238,24 @@ def test_service_rpc_options(self):
service_with_options.node.nodes,
[
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "OneRPC"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
+ ProtoIdentifier("OneRPC"),
+ ProtoEnumOrMessageIdentifier("OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier("OneRPCResponse"),
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "TwoRPC"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
+ ProtoIdentifier("TwoRPC"),
+ ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
False,
False,
[
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(
- None, ProtoStringLiteral(None, "com.example.foo")
- ),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
),
ProtoOption(
- None,
- ProtoFullIdentifier(None, "(foo.bar).baz"),
- ProtoConstant(None, ProtoBool(None, False)),
+ ProtoFullIdentifier("(foo.bar).baz"),
+ ProtoConstant(ProtoBool(False)),
),
],
),
@@ -295,7 +264,6 @@ def test_service_rpc_options(self):
def test_service_parses_comments(self):
service_with_comments = ProtoService.match(
- None,
dedent(
"""
service FooService {
@@ -316,34 +284,29 @@ def test_service_parses_comments(self):
service_with_comments.node.nodes,
[
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "OneRPC"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
+ ProtoIdentifier("OneRPC"),
+ ProtoEnumOrMessageIdentifier("OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier("OneRPCResponse"),
),
- ProtoSingleLineComment(None, " single-line comment!"),
+ ProtoSingleLineComment(" single-line comment!"),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "TwoRPC"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
+ ProtoIdentifier("TwoRPC"),
+ ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
),
ProtoMultiLineComment(
- None,
"\n multiple\n line\n comment\n ",
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "ThreeRPC"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
+ ProtoIdentifier("ThreeRPC"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
),
],
)
def test_service_normalize_removes_comments(self):
normalized_service = ProtoService.match(
- None,
dedent(
"""
service FooService {
@@ -364,22 +327,19 @@ def test_service_normalize_removes_comments(self):
normalized_service.nodes,
[
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "OneRPC"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
+ ProtoIdentifier("OneRPC"),
+ ProtoEnumOrMessageIdentifier("OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier("OneRPCResponse"),
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "ThreeRPC"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
+ ProtoIdentifier("ThreeRPC"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "TwoRPC"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
+ ProtoIdentifier("TwoRPC"),
+ ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
),
],
)
diff --git a/test/proto_string_literal_test.py b/test/proto_string_literal_test.py
index b3bb303..73ad4dc 100644
--- a/test/proto_string_literal_test.py
+++ b/test/proto_string_literal_test.py
@@ -5,33 +5,33 @@
class StringLiteralTest(unittest.TestCase):
def test_correct_syntax(self):
- parsed_single_quote = ProtoStringLiteral.match(None, """'foo'""")
+ parsed_single_quote = ProtoStringLiteral.match("""'foo'""")
self.assertEqual(parsed_single_quote.node.value, "foo")
self.assertEqual(parsed_single_quote.remaining_source, "")
self.assertEqual(parsed_single_quote.node.serialize(), "'foo'")
- parsed_double_quote = ProtoStringLiteral.match(None, """\"foo\"""")
+ parsed_double_quote = ProtoStringLiteral.match("""\"foo\"""")
self.assertEqual(parsed_double_quote.node.value, "foo")
self.assertEqual(parsed_double_quote.remaining_source, "")
self.assertEqual(parsed_double_quote.node.serialize(), '"foo"')
def test_remaining_source(self):
- parsed_single_quote = ProtoStringLiteral.match(None, """'foo'\nbar baz""")
+ parsed_single_quote = ProtoStringLiteral.match("""'foo'\nbar baz""")
self.assertEqual(parsed_single_quote.remaining_source, "bar baz")
- parsed_double_quote = ProtoStringLiteral.match(None, """\"foo\"\"foobar\"""")
+ parsed_double_quote = ProtoStringLiteral.match("""\"foo\"\"foobar\"""")
self.assertEqual(parsed_double_quote.remaining_source, '"foobar"')
def test_missing_quote(self):
- self.assertIsNone(ProtoStringLiteral.match(None, """'foo"""))
- self.assertIsNone(ProtoStringLiteral.match(None, """foo'"""))
- self.assertIsNone(ProtoStringLiteral.match(None, """\"foo"""))
- self.assertIsNone(ProtoStringLiteral.match(None, """foo\""""))
- self.assertIsNone(ProtoStringLiteral.match(None, """'foo\""""))
- self.assertIsNone(ProtoStringLiteral.match(None, """\"foo'"""))
+ self.assertIsNone(ProtoStringLiteral.match("""'foo"""))
+ self.assertIsNone(ProtoStringLiteral.match("""foo'"""))
+ self.assertIsNone(ProtoStringLiteral.match("""\"foo"""))
+ self.assertIsNone(ProtoStringLiteral.match("""foo\""""))
+ self.assertIsNone(ProtoStringLiteral.match("""'foo\""""))
+ self.assertIsNone(ProtoStringLiteral.match("""\"foo'"""))
def test_escaped_quote(self):
- self.assertIsNone(ProtoStringLiteral.match(None, """'foo\\'"""))
- self.assertIsNone(ProtoStringLiteral.match(None, """\"foo\\\""""))
- parsed_escaped_quote = ProtoStringLiteral.match(None, """\"foo\\\"barbaz\"""")
+ self.assertIsNone(ProtoStringLiteral.match("""'foo\\'"""))
+ self.assertIsNone(ProtoStringLiteral.match("""\"foo\\\""""))
+ parsed_escaped_quote = ProtoStringLiteral.match("""\"foo\\\"barbaz\"""")
self.assertEqual(parsed_escaped_quote.node.value, 'foo\\"barbaz')
self.assertEqual(parsed_escaped_quote.remaining_source, "")
self.assertEqual(parsed_escaped_quote.node.serialize(), '"foo\\"barbaz"')
diff --git a/test/proto_syntax_test.py b/test/proto_syntax_test.py
index d0e4a3f..6abfda1 100644
--- a/test/proto_syntax_test.py
+++ b/test/proto_syntax_test.py
@@ -7,88 +7,88 @@
class SyntaxTest(unittest.TestCase):
def test_correct_syntax(self):
self.assertEqual(
- ProtoSyntax.match(None, "syntax = 'proto3';").node.syntax.value, "proto3"
+ ProtoSyntax.match("syntax = 'proto3';").node.syntax.value, "proto3"
)
self.assertEqual(
- ProtoSyntax.match(None, 'syntax = "proto3";').node.syntax.value, "proto3"
+ ProtoSyntax.match('syntax = "proto3";').node.syntax.value, "proto3"
)
self.assertEqual(
- ProtoSyntax.match(None, "syntax = 'proto2';").node.syntax.value, "proto2"
+ ProtoSyntax.match("syntax = 'proto2';").node.syntax.value, "proto2"
)
self.assertEqual(
- ProtoSyntax.match(None, 'syntax = "proto2";').node.syntax.value, "proto2"
+ ProtoSyntax.match('syntax = "proto2";').node.syntax.value, "proto2"
)
def test_serialize(self):
self.assertEqual(
- ProtoSyntax.match(None, "syntax = 'proto3';").node.serialize(),
+ ProtoSyntax.match("syntax = 'proto3';").node.serialize(),
"syntax = 'proto3';",
)
self.assertEqual(
- ProtoSyntax.match(None, 'syntax = "proto3";').node.serialize(),
+ ProtoSyntax.match('syntax = "proto3";').node.serialize(),
'syntax = "proto3";',
)
self.assertEqual(
- ProtoSyntax.match(None, "syntax = 'proto2';").node.serialize(),
+ ProtoSyntax.match("syntax = 'proto2';").node.serialize(),
"syntax = 'proto2';",
)
self.assertEqual(
- ProtoSyntax.match(None, 'syntax = "proto2";').node.serialize(),
+ ProtoSyntax.match('syntax = "proto2";').node.serialize(),
'syntax = "proto2";',
)
def test_syntax_not_present(self):
- self.assertIsNone(ProtoSyntax.match(None, ""))
- self.assertIsNone(ProtoSyntax.match(None, 'import "foo.proto";'))
+ self.assertIsNone(ProtoSyntax.match(""))
+ self.assertIsNone(ProtoSyntax.match('import "foo.proto";'))
def test_syntax_malformed(self):
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = 'proto3'")
+ ProtoSyntax.match("syntax = 'proto3'")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, 'syntax = "proto3"')
+ ProtoSyntax.match('syntax = "proto3"')
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = 'proto2'")
+ ProtoSyntax.match("syntax = 'proto2'")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, 'syntax = "proto2"')
+ ProtoSyntax.match('syntax = "proto2"')
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = proto3")
+ ProtoSyntax.match("syntax = proto3")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = proto3;")
+ ProtoSyntax.match("syntax = proto3;")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = 'proto3")
+ ProtoSyntax.match("syntax = 'proto3")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = 'proto3;")
+ ProtoSyntax.match("syntax = 'proto3;")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = proto3'")
+ ProtoSyntax.match("syntax = proto3'")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = proto3';")
+ ProtoSyntax.match("syntax = proto3';")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = 'proton';")
+ ProtoSyntax.match("syntax = 'proton';")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = 'proton'")
+ ProtoSyntax.match("syntax = 'proton'")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = 'proton")
+ ProtoSyntax.match("syntax = 'proton")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = proton';")
+ ProtoSyntax.match("syntax = proton';")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = proton'")
+ ProtoSyntax.match("syntax = proton'")
with self.assertRaises(ValueError):
- ProtoSyntax.match(None, "syntax = proton")
+ ProtoSyntax.match("syntax = proton")
def test_diff_empty_same_syntax_returns_empty(self):
- pf1 = ProtoSyntax(None, ProtoStringLiteral(None, "proto3"))
- pf2 = ProtoSyntax(None, ProtoStringLiteral(None, "proto3"))
+ pf1 = ProtoSyntax(ProtoStringLiteral("proto3"))
+ pf2 = ProtoSyntax(ProtoStringLiteral("proto3"))
self.assertEqual(ProtoSyntax.diff(pf1, pf2), [])
def test_diff_empty_different_syntax_returns_syntax_diff(self):
- pf1 = ProtoSyntax(None, ProtoStringLiteral(None, "proto3"))
- pf2 = ProtoSyntax(None, ProtoStringLiteral(None, "proto2"))
+ pf1 = ProtoSyntax(ProtoStringLiteral("proto3"))
+ pf2 = ProtoSyntax(ProtoStringLiteral("proto2"))
self.assertEqual(
ProtoSyntax.diff(pf1, pf2),
[
ProtoSyntaxChanged(
- ProtoSyntax(None, ProtoStringLiteral(None, "proto3")),
- ProtoSyntax(None, ProtoStringLiteral(None, "proto2")),
+ ProtoSyntax(ProtoStringLiteral("proto3")),
+ ProtoSyntax(ProtoStringLiteral("proto2")),
)
],
)
diff --git a/test/util/parser_test.py b/test/util/parser_test.py
index 08c9470..a610651 100644
--- a/test/util/parser_test.py
+++ b/test/util/parser_test.py
@@ -100,54 +100,45 @@ def test_parser(self):
self.assertEqual(
proto_file.imports,
[
- ProtoImport(None, ProtoStringLiteral(None, "foo.proto"), public=True),
- ProtoImport(None, ProtoStringLiteral(None, "bar/baz.proto"), weak=True),
- ProtoImport(None, ProtoStringLiteral(None, "bat.proto")),
+ ProtoImport(ProtoStringLiteral("foo.proto"), public=True),
+ ProtoImport(ProtoStringLiteral("bar/baz.proto"), weak=True),
+ ProtoImport(ProtoStringLiteral("bat.proto")),
],
)
self.assertEqual(
proto_file.options,
[
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(None, ProtoStringLiteral(None, "my.test.package")),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("my.test.package")),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "(fully.qualified).option"),
- ProtoConstant(
- None, ProtoFloat(None, 3.14159265, ProtoFloatSign.POSITIVE)
- ),
+ ProtoIdentifier("(fully.qualified).option"),
+ ProtoConstant(ProtoFloat(3.14159265, ProtoFloatSign.POSITIVE)),
),
],
)
self.assertIn(
ProtoEnum(
- None,
- ProtoIdentifier(None, "MyAwesomeEnum"),
+ ProtoIdentifier("MyAwesomeEnum"),
[
ProtoOption(
- None,
- ProtoIdentifier(None, "allow_alias"),
- ProtoConstant(None, ProtoBool(None, True)),
+ ProtoIdentifier("allow_alias"),
+ ProtoConstant(ProtoBool(True)),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "MAE_UNSPECIFIED"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("MAE_UNSPECIFIED"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
[],
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "MAE_STARTED"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("MAE_STARTED"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
[],
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "MAE_RUNNING"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("MAE_RUNNING"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
[],
),
],
@@ -156,113 +147,89 @@ def test_parser(self):
)
self.assertIn(
ProtoMessage(
- None,
- ProtoIdentifier(None, "MyAwesomeMessage"),
+ ProtoIdentifier("MyAwesomeMessage"),
[
ProtoOption(
- None,
- ProtoFullIdentifier(None, "(bar).baz"),
- ProtoConstant(
- None, ProtoFloat(None, 1.2, ProtoFloatSign.POSITIVE)
- ),
+ ProtoFullIdentifier("(bar).baz"),
+ ProtoConstant(ProtoFloat(1.2, ProtoFloatSign.POSITIVE)),
),
ProtoEnum(
- None,
- ProtoIdentifier(None, "MyNestedEnum"),
+ ProtoIdentifier("MyNestedEnum"),
[
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "MNE_UNDEFINED"),
- ProtoInt(None, 0, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("MNE_UNDEFINED"),
+ ProtoInt(0, ProtoIntSign.POSITIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "MNE_NEGATIVE"),
- ProtoInt(None, 1, ProtoIntSign.NEGATIVE),
+ ProtoIdentifier("MNE_NEGATIVE"),
+ ProtoInt(1, ProtoIntSign.NEGATIVE),
),
ProtoEnumValue(
- None,
- ProtoIdentifier(None, "MNE_POSITIVE"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("MNE_POSITIVE"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
),
],
),
- ProtoMessage(None, ProtoIdentifier(None, "MyNestedMessage"), []),
+ ProtoMessage(ProtoIdentifier("MyNestedMessage"), []),
ProtoReserved(
- None,
ranges=[
ProtoRange(
- None,
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
- ProtoInt(None, 3, ProtoIntSign.POSITIVE),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
+ ProtoInt(3, ProtoIntSign.POSITIVE),
)
],
),
- ProtoReserved(None, fields=[ProtoIdentifier(None, "yay")]),
- ProtoSingleLineComment(None, " testing nested comment"),
+ ProtoReserved(fields=[ProtoIdentifier("yay")]),
+ ProtoSingleLineComment(" testing nested comment"),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "field_one"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("field_one"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
True,
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "field_two"),
- ProtoInt(None, 2, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("field_two"),
+ ProtoInt(2, ProtoIntSign.POSITIVE),
False,
False,
- ProtoIdentifier(None, "MyNestedMessage"),
+ ProtoIdentifier("MyNestedMessage"),
[
ProtoMessageFieldOption(
- None,
- ProtoFullIdentifier(None, "bar.baz"),
- ProtoConstant(None, ProtoBool(None, True)),
+ ProtoFullIdentifier("bar.baz"),
+ ProtoConstant(ProtoBool(True)),
)
],
),
- ProtoExtensions(None, [ProtoRange(None, 8, ProtoRangeEnum.MAX)]),
+ ProtoExtensions([ProtoRange(8, ProtoRangeEnum.MAX)]),
ProtoOneOf(
- None,
- ProtoIdentifier(None, "foo"),
+ ProtoIdentifier("foo"),
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "name"),
- ProtoInt(None, 4, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
),
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(
- None, ProtoStringLiteral(None, "com.example.foo")
- ),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
),
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "sub_message"),
- ProtoInt(None, 9, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("sub_message"),
+ ProtoInt(9, ProtoIntSign.POSITIVE),
False,
False,
- ProtoFullIdentifier(None, "SubMessage"),
+ ProtoFullIdentifier("SubMessage"),
[
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "(bar.baz).bat"),
- ProtoConstant(
- None, ProtoStringLiteral(None, "bat")
- ),
+ ProtoIdentifier("(bar.baz).bat"),
+ ProtoConstant(ProtoStringLiteral("bat")),
),
ProtoMessageFieldOption(
- None,
- ProtoIdentifier(None, "baz.bat"),
+ ProtoIdentifier("baz.bat"),
ProtoConstant(
- None,
- ProtoInt(None, 100, ProtoIntSign.NEGATIVE),
+ ProtoInt(100, ProtoIntSign.NEGATIVE),
),
),
],
@@ -270,12 +237,11 @@ def test_parser(self):
],
),
ProtoMap(
- None,
ProtoMapKeyTypesEnum.SFIXED64,
ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier(None, "my_map"),
- ProtoInt(None, 10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier(None, "NestedMessage"),
+ ProtoIdentifier("my_map"),
+ ProtoInt(10, ProtoIntSign.POSITIVE),
+ ProtoEnumOrMessageIdentifier("NestedMessage"),
[],
),
],
@@ -285,47 +251,38 @@ def test_parser(self):
self.assertIn(
ProtoService(
- None,
- ProtoIdentifier(None, "MyGreatService"),
+ ProtoIdentifier("MyGreatService"),
[
ProtoOption(
- None,
- ProtoIdentifier(None, "(foo.bar).baz"),
- ProtoConstant(None, ProtoStringLiteral(None, "bat")),
+ ProtoIdentifier("(foo.bar).baz"),
+ ProtoConstant(ProtoStringLiteral("bat")),
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "OneRPC"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "OneRPCResponse"),
+ ProtoIdentifier("OneRPC"),
+ ProtoEnumOrMessageIdentifier("OneRPCRequest"),
+ ProtoEnumOrMessageIdentifier("OneRPCResponse"),
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "TwoRPC"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "TwoRPCResponse"),
+ ProtoIdentifier("TwoRPC"),
+ ProtoEnumOrMessageIdentifier("TwoRPCRequest"),
+ ProtoEnumOrMessageIdentifier("TwoRPCResponse"),
False,
True,
),
ProtoServiceRPC(
- None,
- ProtoIdentifier(None, "ThreeRPC"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCRequest"),
- ProtoEnumOrMessageIdentifier(None, "ThreeRPCResponse"),
+ ProtoIdentifier("ThreeRPC"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCRequest"),
+ ProtoEnumOrMessageIdentifier("ThreeRPCResponse"),
False,
False,
[
ProtoOption(
- None,
- ProtoIdentifier(None, "java_package"),
- ProtoConstant(
- None, ProtoStringLiteral(None, "com.example.foo")
- ),
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
),
ProtoOption(
- None,
- ProtoFullIdentifier(None, "(foo.bar).baz"),
- ProtoConstant(None, ProtoBool(None, False)),
+ ProtoFullIdentifier("(foo.bar).baz"),
+ ProtoConstant(ProtoBool(False)),
),
],
),
@@ -336,16 +293,14 @@ def test_parser(self):
self.assertIn(
ProtoExtend(
- None,
- ProtoIdentifier(None, "SomeExtendableMessage"),
+ ProtoIdentifier("SomeExtendableMessage"),
[
ProtoMessageField(
- None,
ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier(None, "some_extendable_field"),
- ProtoInt(None, 1, ProtoIntSign.POSITIVE),
+ ProtoIdentifier("some_extendable_field"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
),
- ProtoSingleLineComment(None, " yay"),
+ ProtoSingleLineComment(" yay"),
],
),
proto_file.nodes,
From 91898489414e2d0bc1e64cca0ee0f7c5e62e12ea Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Mon, 20 Feb 2023 22:44:23 -0500
Subject: [PATCH 19/35] Break out oneof tests into separate file (#76)
---
test/BUILD.bazel | 15 +++
test/proto_message_test.py | 259 +------------------------------------
test/proto_oneof_test.py | 202 +++++++++++++++++++++++++++++
3 files changed, 219 insertions(+), 257 deletions(-)
create mode 100644 test/proto_oneof_test.py
diff --git a/test/BUILD.bazel b/test/BUILD.bazel
index 47cd15a..836c370 100644
--- a/test/BUILD.bazel
+++ b/test/BUILD.bazel
@@ -145,6 +145,21 @@ py_test(
],
)
+py_test(
+ name = "proto_oneof_test",
+ srcs = ["proto_oneof_test.py"],
+ deps = [
+ "//src:proto_comment",
+ "//src:proto_constant",
+ "//src:proto_identifier",
+ "//src:proto_int",
+ "//src:proto_message_field",
+ "//src:proto_oneof",
+ "//src:proto_option",
+ "//src:proto_string_literal",
+ ],
+)
+
py_test(
name = "proto_message_test",
srcs = ["proto_message_test.py"],
diff --git a/test/proto_message_test.py b/test/proto_message_test.py
index fa4a5ae..1eae4f6 100644
--- a/test/proto_message_test.py
+++ b/test/proto_message_test.py
@@ -14,17 +14,13 @@
)
from src.proto_int import ProtoInt, ProtoIntSign
from src.proto_map import ProtoMap, ProtoMapKeyTypesEnum, ProtoMapValueTypesEnum
-from src.proto_message import (
- ProtoMessage,
- ProtoMessageAdded,
- ProtoMessageRemoved,
- ProtoOneOf,
-)
+from src.proto_message import ProtoMessage, ProtoMessageAdded, ProtoMessageRemoved
from src.proto_message_field import (
ProtoMessageField,
ProtoMessageFieldOption,
ProtoMessageFieldTypesEnum,
)
+from src.proto_oneof import ProtoOneOf
from src.proto_option import ProtoOption
from src.proto_range import ProtoRange, ProtoRangeEnum
from src.proto_reserved import ProtoReserved
@@ -397,257 +393,6 @@ def test_message_simple_field(self):
),
)
- def test_oneof_empty(self):
- parsed_oneof_empty = ProtoOneOf.match(dedent("oneof one_of_field {}".strip()))
- self.assertEqual(
- parsed_oneof_empty.node,
- ProtoOneOf(
- ProtoIdentifier("one_of_field"),
- [],
- ),
- )
-
- def test_oneof_empty_statements(self):
- parsed_oneof_empty = ProtoOneOf.match(
- dedent(
- """oneof one_of_field {
- ;
- ;
- }""".strip()
- ),
- )
- self.assertEqual(
- parsed_oneof_empty.node,
- ProtoOneOf(
- ProtoIdentifier("one_of_field"),
- [],
- ),
- )
-
- def test_oneof_basic_fields(self):
- parsed_oneof_basic_fields = ProtoOneOf.match(
- dedent(
- """oneof one_of_field {
- string name = 4;
- SubMessage sub_message = 9;
- }""".strip()
- ),
- )
- self.assertEqual(
- parsed_oneof_basic_fields.node,
- ProtoOneOf(
- ProtoIdentifier("one_of_field"),
- [
- ProtoMessageField(
- ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
- ),
- ProtoMessageField(
- ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("sub_message"),
- ProtoInt(9, ProtoIntSign.POSITIVE),
- False,
- False,
- ProtoFullIdentifier("SubMessage"),
- [],
- ),
- ],
- ),
- )
-
- def test_oneof_options(self):
- parsed_oneof_options = ProtoOneOf.match(
- dedent(
- """oneof one_of_field {
- option java_package = "com.example.foo";
- }""".strip()
- ),
- )
- self.assertEqual(
- parsed_oneof_options.node,
- ProtoOneOf(
- ProtoIdentifier("one_of_field"),
- [
- ProtoOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
- ),
- ],
- ),
- )
-
- def test_oneof_field_option(self):
- parsed_oneof_field_option = ProtoOneOf.match(
- dedent(
- """oneof one_of_field {
- string name = 4 [ (bar.baz).bat = "bat", baz.bat = -100 ];
- }""".strip()
- ),
- )
- self.assertEqual(
- parsed_oneof_field_option.node,
- ProtoOneOf(
- ProtoIdentifier("one_of_field"),
- [
- ProtoMessageField(
- ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
- False,
- False,
- None,
- [
- ProtoMessageFieldOption(
- ProtoIdentifier("(bar.baz).bat"),
- ProtoConstant(ProtoStringLiteral("bat")),
- ),
- ProtoMessageFieldOption(
- ProtoIdentifier("baz.bat"),
- ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
- ),
- ],
- )
- ],
- ),
- )
-
- def test_oneof_with_comment(self):
- parsed_oneof_with_comment = ProtoOneOf.match(
- dedent(
- """oneof one_of_field {
- string name = 4;
- // single-line comment!
- SubMessage sub_message = 9;
- }""".strip()
- ),
- )
- self.assertEqual(
- parsed_oneof_with_comment.node,
- ProtoOneOf(
- ProtoIdentifier("one_of_field"),
- [
- ProtoMessageField(
- ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
- ),
- ProtoSingleLineComment(" single-line comment!"),
- ProtoMessageField(
- ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("sub_message"),
- ProtoInt(9, ProtoIntSign.POSITIVE),
- False,
- False,
- ProtoFullIdentifier("SubMessage"),
- [],
- ),
- ],
- ),
- )
-
- def test_oneof_normalize_removes_comment(self):
- normalized_oneof = ProtoOneOf.match(
- dedent(
- """oneof one_of_field {
- string name = 4;
- // single-line comment!
- SubMessage sub_message = 9;
- }""".strip()
- ),
- ).node.normalize()
- self.assertEqual(
- normalized_oneof.nodes,
- [
- ProtoMessageField(
- ProtoMessageFieldTypesEnum.STRING,
- ProtoIdentifier("name"),
- ProtoInt(4, ProtoIntSign.POSITIVE),
- ),
- ProtoMessageField(
- ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("sub_message"),
- ProtoInt(9, ProtoIntSign.POSITIVE),
- False,
- False,
- ProtoFullIdentifier("SubMessage"),
- [],
- ),
- ],
- )
-
- def test_simple_map(self):
- parsed_map_simple = ProtoMap.match("map my_map = 10;")
- self.assertEqual(
- parsed_map_simple.node,
- ProtoMap(
- ProtoMapKeyTypesEnum.SFIXED64,
- ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("my_map"),
- ProtoInt(10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier("NestedMessage"),
- [],
- ),
- )
-
- def test_map_without_spaces(self):
- map_without_spaces = ProtoMap.match("map my_map = 10;")
- self.assertEqual(
- map_without_spaces.node,
- ProtoMap(
- ProtoMapKeyTypesEnum.SFIXED64,
- ProtoMapValueTypesEnum.ENUM_OR_MESSAGE,
- ProtoIdentifier("my_map"),
- ProtoInt(10, ProtoIntSign.POSITIVE),
- ProtoEnumOrMessageIdentifier("NestedMessage"),
- [],
- ),
- )
-
- def test_map_with_options(self):
- parsed_map_simple = ProtoMap.match(
- "map my_map = 10 [ java_package = 'com.example.foo', baz.bat = 48 ];",
- )
- self.assertEqual(parsed_map_simple.node.key_type, ProtoMapKeyTypesEnum.SFIXED64)
- self.assertEqual(
- parsed_map_simple.node.value_type, ProtoMapValueTypesEnum.ENUM_OR_MESSAGE
- )
- self.assertEqual(parsed_map_simple.node.name, ProtoIdentifier("my_map"))
- self.assertEqual(
- parsed_map_simple.node.number, ProtoInt(10, ProtoIntSign.POSITIVE)
- )
- self.assertEqual(
- parsed_map_simple.node.enum_or_message_type_name,
- ProtoEnumOrMessageIdentifier("NestedMessage"),
- )
- self.assertEqual(
- parsed_map_simple.node.options,
- [
- ProtoMessageFieldOption(
- ProtoIdentifier("java_package"),
- ProtoConstant(ProtoStringLiteral("com.example.foo")),
- ),
- ProtoMessageFieldOption(
- ProtoFullIdentifier("baz.bat"),
- ProtoConstant(ProtoInt(48, ProtoIntSign.POSITIVE)),
- ),
- ],
- )
-
- def test_map_message_value(self):
- parsed_map_simple = ProtoMap.match("map string_map = 11;")
- self.assertEqual(
- parsed_map_simple.node,
- ProtoMap(
- ProtoMapKeyTypesEnum.STRING,
- ProtoMapValueTypesEnum.STRING,
- ProtoIdentifier("string_map"),
- ProtoInt(11, ProtoIntSign.POSITIVE),
- None,
- [],
- ),
- )
-
def test_message_parses_comments(self):
parsed_comments = ProtoMessage.match(
dedent(
diff --git a/test/proto_oneof_test.py b/test/proto_oneof_test.py
new file mode 100644
index 0000000..0f0eec3
--- /dev/null
+++ b/test/proto_oneof_test.py
@@ -0,0 +1,202 @@
+import unittest
+from textwrap import dedent
+
+from src.proto_comment import ProtoSingleLineComment
+from src.proto_constant import ProtoConstant
+from src.proto_identifier import ProtoFullIdentifier, ProtoIdentifier
+from src.proto_int import ProtoInt, ProtoIntSign
+from src.proto_message_field import (
+ ProtoMessageField,
+ ProtoMessageFieldOption,
+ ProtoMessageFieldTypesEnum,
+)
+from src.proto_oneof import ProtoOneOf
+from src.proto_option import ProtoOption
+from src.proto_string_literal import ProtoStringLiteral
+
+
+class OneOfTest(unittest.TestCase):
+ maxDiff = None
+
+ def test_oneof_empty(self):
+ parsed_oneof_empty = ProtoOneOf.match(dedent("oneof one_of_field {}".strip()))
+ self.assertEqual(
+ parsed_oneof_empty.node,
+ ProtoOneOf(
+ ProtoIdentifier("one_of_field"),
+ [],
+ ),
+ )
+
+ def test_oneof_empty_statements(self):
+ parsed_oneof_empty = ProtoOneOf.match(
+ dedent(
+ """oneof one_of_field {
+ ;
+ ;
+ }""".strip()
+ ),
+ )
+ self.assertEqual(
+ parsed_oneof_empty.node,
+ ProtoOneOf(
+ ProtoIdentifier("one_of_field"),
+ [],
+ ),
+ )
+
+ def test_oneof_basic_fields(self):
+ parsed_oneof_basic_fields = ProtoOneOf.match(
+ dedent(
+ """oneof one_of_field {
+ string name = 4;
+ SubMessage sub_message = 9;
+ }""".strip()
+ ),
+ )
+ self.assertEqual(
+ parsed_oneof_basic_fields.node,
+ ProtoOneOf(
+ ProtoIdentifier("one_of_field"),
+ [
+ ProtoMessageField(
+ ProtoMessageFieldTypesEnum.STRING,
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
+ ProtoIdentifier("sub_message"),
+ ProtoInt(9, ProtoIntSign.POSITIVE),
+ False,
+ False,
+ ProtoFullIdentifier("SubMessage"),
+ [],
+ ),
+ ],
+ ),
+ )
+
+ def test_oneof_options(self):
+ parsed_oneof_options = ProtoOneOf.match(
+ dedent(
+ """oneof one_of_field {
+ option java_package = "com.example.foo";
+ }""".strip()
+ ),
+ )
+ self.assertEqual(
+ parsed_oneof_options.node,
+ ProtoOneOf(
+ ProtoIdentifier("one_of_field"),
+ [
+ ProtoOption(
+ ProtoIdentifier("java_package"),
+ ProtoConstant(ProtoStringLiteral("com.example.foo")),
+ ),
+ ],
+ ),
+ )
+
+ def test_oneof_field_option(self):
+ parsed_oneof_field_option = ProtoOneOf.match(
+ dedent(
+ """oneof one_of_field {
+ string name = 4 [ (bar.baz).bat = "bat", baz.bat = -100 ];
+ }""".strip()
+ ),
+ )
+ self.assertEqual(
+ parsed_oneof_field_option.node,
+ ProtoOneOf(
+ ProtoIdentifier("one_of_field"),
+ [
+ ProtoMessageField(
+ ProtoMessageFieldTypesEnum.STRING,
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
+ False,
+ False,
+ None,
+ [
+ ProtoMessageFieldOption(
+ ProtoIdentifier("(bar.baz).bat"),
+ ProtoConstant(ProtoStringLiteral("bat")),
+ ),
+ ProtoMessageFieldOption(
+ ProtoIdentifier("baz.bat"),
+ ProtoConstant(ProtoInt(100, ProtoIntSign.NEGATIVE)),
+ ),
+ ],
+ )
+ ],
+ ),
+ )
+
+ def test_oneof_with_comment(self):
+ parsed_oneof_with_comment = ProtoOneOf.match(
+ dedent(
+ """oneof one_of_field {
+ string name = 4;
+ // single-line comment!
+ SubMessage sub_message = 9;
+ }""".strip()
+ ),
+ )
+ self.assertEqual(
+ parsed_oneof_with_comment.node,
+ ProtoOneOf(
+ ProtoIdentifier("one_of_field"),
+ [
+ ProtoMessageField(
+ ProtoMessageFieldTypesEnum.STRING,
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
+ ),
+ ProtoSingleLineComment(" single-line comment!"),
+ ProtoMessageField(
+ ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
+ ProtoIdentifier("sub_message"),
+ ProtoInt(9, ProtoIntSign.POSITIVE),
+ False,
+ False,
+ ProtoFullIdentifier("SubMessage"),
+ [],
+ ),
+ ],
+ ),
+ )
+
+ def test_oneof_normalize_removes_comment(self):
+ normalized_oneof = ProtoOneOf.match(
+ dedent(
+ """oneof one_of_field {
+ string name = 4;
+ // single-line comment!
+ SubMessage sub_message = 9;
+ }""".strip()
+ ),
+ ).node.normalize()
+ self.assertEqual(
+ normalized_oneof.nodes,
+ [
+ ProtoMessageField(
+ ProtoMessageFieldTypesEnum.STRING,
+ ProtoIdentifier("name"),
+ ProtoInt(4, ProtoIntSign.POSITIVE),
+ ),
+ ProtoMessageField(
+ ProtoMessageFieldTypesEnum.ENUM_OR_MESSAGE,
+ ProtoIdentifier("sub_message"),
+ ProtoInt(9, ProtoIntSign.POSITIVE),
+ False,
+ False,
+ ProtoFullIdentifier("SubMessage"),
+ [],
+ ),
+ ],
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
From 0f8d56d9b9ec1be302f320ac7cca5738c28316d8 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Mon, 20 Feb 2023 22:46:40 -0500
Subject: [PATCH 20/35] Specify a direct dep that we're missing (#77)
---
test/BUILD.bazel | 2 ++
1 file changed, 2 insertions(+)
diff --git a/test/BUILD.bazel b/test/BUILD.bazel
index 836c370..69fd827 100644
--- a/test/BUILD.bazel
+++ b/test/BUILD.bazel
@@ -174,6 +174,8 @@ py_test(
"//src:proto_int",
"//src:proto_map",
"//src:proto_message",
+ "//src:proto_message_field",
+ "//src:proto_oneof",
"//src:proto_option",
"//src:proto_reserved",
"//src:proto_string_literal",
From b30ad8873b2fa741763d6bb752fc6a42ac86ebfd Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Wed, 8 Mar 2023 11:11:59 -0400
Subject: [PATCH 21/35] Make ProtoFile a ProtoNode subclass (#78)
---
src/BUILD.bazel | 3 ++
src/proto_file.py | 100 +++++++++++++++++++++++++++++++++++++++++--
src/util/BUILD.bazel | 9 ----
src/util/parser.py | 90 ++++----------------------------------
4 files changed, 108 insertions(+), 94 deletions(-)
diff --git a/src/BUILD.bazel b/src/BUILD.bazel
index 13dfe8f..c11c756 100644
--- a/src/BUILD.bazel
+++ b/src/BUILD.bazel
@@ -248,12 +248,15 @@ py_library(
srcs = ["proto_file.py"],
visibility = ["//visibility:public"],
deps = [
+ ":proto_comment",
":proto_enum",
+ ":proto_extend",
":proto_import",
":proto_message",
":proto_node",
":proto_option",
":proto_package",
+ ":proto_service",
":proto_syntax",
],
)
diff --git a/src/proto_file.py b/src/proto_file.py
index adcd7f8..a5bdd46 100644
--- a/src/proto_file.py
+++ b/src/proto_file.py
@@ -1,16 +1,29 @@
from typing import Optional, Sequence
+from src.proto_comment import (
+ ProtoComment,
+ ProtoMultiLineComment,
+ ProtoSingleLineComment,
+)
from src.proto_enum import ProtoEnum
+from src.proto_extend import ProtoExtend
from src.proto_import import ProtoImport
from src.proto_message import ProtoMessage
-from src.proto_node import ProtoNode, ProtoNodeDiff
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
from src.proto_option import ProtoOption
from src.proto_package import ProtoPackage
+from src.proto_service import ProtoService
from src.proto_syntax import ProtoSyntax
-class ProtoFile:
- def __init__(self, syntax: ProtoSyntax, nodes: list[ProtoNode]):
+class ParsedProtoFileNode(ParsedProtoNode):
+ node: "ProtoFile"
+ remaining_source: str
+
+
+class ProtoFile(ProtoNode):
+ def __init__(self, syntax: ProtoSyntax, nodes: list[ProtoNode], *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.syntax = syntax
self.nodes = nodes
@@ -40,6 +53,87 @@ def enums(self) -> list[ProtoEnum]:
def messages(self) -> list[ProtoMessage]:
return [node for node in self.nodes if isinstance(node, ProtoMessage)]
+ @staticmethod
+ def parse_partial_content(partial_proto_content: str) -> ParsedProtoNode:
+ node_types: list[type[ProtoNode]] = [
+ ProtoImport,
+ ProtoMessage,
+ ProtoPackage,
+ ProtoOption,
+ ProtoEnum,
+ ProtoExtend,
+ ProtoService,
+ ProtoSingleLineComment,
+ ProtoMultiLineComment,
+ ]
+ for node_type in node_types:
+ try:
+ match_result = node_type.match(partial_proto_content)
+ except (ValueError, IndexError, TypeError):
+ raise ValueError(
+ f"Could not parse proto content:\n{partial_proto_content}"
+ )
+ if match_result is not None:
+ return match_result
+ raise ValueError(f"Could not parse proto content:\n{partial_proto_content}")
+
+ @staticmethod
+ def parse_syntax_and_preceding_comments(
+ proto_content: str,
+ ) -> tuple[ProtoSyntax, Sequence[ProtoComment], str]:
+ # First, parse any preceding comments.
+ parsed_tree = []
+ while True:
+ for node_type in [ProtoSingleLineComment, ProtoMultiLineComment]:
+ try:
+ match_result = node_type.match(proto_content)
+ except (ValueError, IndexError, TypeError):
+ raise ValueError(f"Could not parse proto content:\n{proto_content}")
+ if match_result is not None:
+ parsed_tree.append(match_result.node)
+ proto_content = match_result.remaining_source.strip()
+ break
+ if match_result is None:
+ break
+
+ # Next, parse syntax.
+ try:
+ syntax_match = ProtoSyntax.match(proto_content.strip())
+ except (ValueError, IndexError, TypeError):
+ raise ValueError(f"Proto doesn't have parseable syntax:\n{proto_content}")
+ if syntax_match is None:
+ raise ValueError(f"Proto doesn't have parseable syntax:\n{proto_content}")
+ syntax = syntax_match.node
+ proto_content = syntax_match.remaining_source.strip()
+
+ return syntax, parsed_tree, proto_content
+
+ @classmethod
+ def match(
+ cls, proto_content: str, parent: Optional["ProtoNode"] = None
+ ) -> Optional[ParsedProtoFileNode]:
+ syntax, parsed_tree, proto_content = cls.parse_syntax_and_preceding_comments(
+ proto_content
+ )
+ new_tree: list[ProtoNode] = list(parsed_tree)
+ while proto_content:
+ # Remove empty statements.
+ if proto_content.startswith(";"):
+ proto_content = proto_content[1:].strip()
+ continue
+ match_result = cls.parse_partial_content(proto_content)
+ new_tree.append(match_result.node)
+ proto_content = match_result.remaining_source.strip()
+
+ return ParsedProtoFileNode(cls(syntax, new_tree), proto_content)
+
+ def normalize(self) -> Optional["ProtoNode"]:
+ normalized_nodes = [n.normalize() for n in self.nodes]
+ return ProtoFile(
+ syntax=self.syntax.normalize(),
+ nodes=[n for n in normalized_nodes if n is not None],
+ )
+
def serialize(self) -> str:
serialized_parts = [self.syntax.serialize()]
previous_type: type[ProtoNode] = self.syntax.__class__
diff --git a/src/util/BUILD.bazel b/src/util/BUILD.bazel
index 827decd..03f3423 100644
--- a/src/util/BUILD.bazel
+++ b/src/util/BUILD.bazel
@@ -5,16 +5,7 @@ py_library(
srcs = ["parser.py"],
visibility = ["//visibility:public"],
deps = [
- "//src:proto_enum",
- "//src:proto_extend",
"//src:proto_file",
- "//src:proto_import",
- "//src:proto_message",
- "//src:proto_node",
- "//src:proto_option",
- "//src:proto_package",
- "//src:proto_service",
- "//src:proto_syntax",
],
)
diff --git a/src/util/parser.py b/src/util/parser.py
index 75b9de9..dd00352 100644
--- a/src/util/parser.py
+++ b/src/util/parser.py
@@ -1,21 +1,6 @@
import sys
-from typing import Sequence
-from src.proto_comment import (
- ProtoComment,
- ProtoMultiLineComment,
- ProtoSingleLineComment,
-)
-from src.proto_enum import ProtoEnum
-from src.proto_extend import ProtoExtend
from src.proto_file import ProtoFile
-from src.proto_import import ProtoImport
-from src.proto_message import ProtoMessage
-from src.proto_node import ParsedProtoNode, ProtoNode
-from src.proto_option import ProtoOption
-from src.proto_package import ProtoPackage
-from src.proto_service import ProtoService
-from src.proto_syntax import ProtoSyntax
class ParseError(ValueError):
@@ -24,76 +9,17 @@ class ParseError(ValueError):
class Parser:
@staticmethod
- def parse_partial_content(partial_proto_content: str) -> ParsedProtoNode:
- node_types: list[type[ProtoNode]] = [
- ProtoImport,
- ProtoMessage,
- ProtoPackage,
- ProtoOption,
- ProtoEnum,
- ProtoExtend,
- ProtoService,
- ProtoSingleLineComment,
- ProtoMultiLineComment,
- ]
- for node_type in node_types:
- try:
- match_result = node_type.match(partial_proto_content)
- except (ValueError, IndexError, TypeError):
- raise ParseError(
- f"Could not parse proto content:\n{partial_proto_content}"
- )
- if match_result is not None:
- return match_result
- raise ParseError(f"Could not parse proto content:\n{partial_proto_content}")
-
- @staticmethod
- def parse_syntax_and_preceding_comments(
- proto_content: str,
- ) -> tuple[ProtoSyntax, Sequence[ProtoComment], str]:
- # First, parse any preceding comments.
- parsed_tree = []
- while True:
- for node_type in [ProtoSingleLineComment, ProtoMultiLineComment]:
- try:
- match_result = node_type.match(proto_content)
- except (ValueError, IndexError, TypeError):
- raise ParseError(f"Could not parse proto content:\n{proto_content}")
- if match_result is not None:
- parsed_tree.append(match_result.node)
- proto_content = match_result.remaining_source.strip()
- break
- if match_result is None:
- break
-
- # Next, parse syntax.
+ def loads(proto_content: str) -> ProtoFile:
try:
- syntax_match = ProtoSyntax.match(proto_content.strip())
- except (ValueError, IndexError, TypeError):
- raise ParseError(f"Proto doesn't have parseable syntax:\n{proto_content}")
- if syntax_match is None:
+ parsed_file = ProtoFile.match(proto_content, None)
+ except ValueError as e:
+ raise ParseError(
+ f"Proto doesn't have parseable syntax:\n{proto_content}\n{e}"
+ )
+ if parsed_file is None:
raise ParseError(f"Proto doesn't have parseable syntax:\n{proto_content}")
- syntax = syntax_match.node
- proto_content = syntax_match.remaining_source.strip()
-
- return syntax, parsed_tree, proto_content
-
- @staticmethod
- def loads(proto_content: str) -> ProtoFile:
- syntax, parsed_tree, proto_content = Parser.parse_syntax_and_preceding_comments(
- proto_content
- )
- new_tree: list[ProtoNode] = list(parsed_tree)
- while proto_content:
- # Remove empty statements.
- if proto_content.startswith(";"):
- proto_content = proto_content[1:].strip()
- continue
- match_result = Parser.parse_partial_content(proto_content)
- new_tree.append(match_result.node)
- proto_content = match_result.remaining_source.strip()
- return ProtoFile(syntax, new_tree)
+ return parsed_file.node
if __name__ == "__main__":
From 0b12d272cc2147d9d62164d17723cc32abf25b1c Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Thu, 9 Mar 2023 10:14:41 -0400
Subject: [PATCH 22/35] Support oneof diffs in messages (#79)
---
TODO.md | 1 +
src/proto_enum.py | 41 ++++--
src/proto_file.py | 4 +-
src/proto_message.py | 53 ++++++--
src/proto_message_field.py | 2 +-
src/proto_oneof.py | 83 +++++++++++-
src/proto_option.py | 56 +++++---
test/proto_enum_test.py | 47 +++++--
test/proto_message_test.py | 96 +++++++++-----
test/proto_oneof_test.py | 259 ++++++++++++++++++++++++++++++++++++-
test/proto_option_test.py | 82 +++++++-----
11 files changed, 603 insertions(+), 121 deletions(-)
diff --git a/TODO.md b/TODO.md
index 0ade4bf..2ac2e2c 100644
--- a/TODO.md
+++ b/TODO.md
@@ -84,6 +84,7 @@
- [ ] RPC changes
- [ ] Additions/removals
- [ ] Option changes
+ - [ ] Comment diffs
- [ ] Backwards-compatibility check
- [ ] __eq__ should enforce parent equality
- [ ] Scoping of diffs under containing objects
diff --git a/src/proto_enum.py b/src/proto_enum.py
index b427221..a37bd07 100644
--- a/src/proto_enum.py
+++ b/src/proto_enum.py
@@ -182,7 +182,9 @@ def diff(
f"Don't know how to handle diff between enums whose names aren't identical: {before}, {after}"
)
- diffs.extend(ProtoEnumValueOption.diff_sets(before.options, after.options))
+ diffs.extend(
+ ProtoEnumValueOption.diff_sets(before, before.options, after.options)
+ )
return diffs
@staticmethod
@@ -323,11 +325,13 @@ def serialize(self) -> str:
return "\n".join(serialize_parts)
@staticmethod
- def diff(before: "ProtoEnum", after: "ProtoEnum") -> list["ProtoNodeDiff"]:
+ def diff(
+ parent: ProtoNode, before: "ProtoEnum", after: "ProtoEnum"
+ ) -> list["ProtoNodeDiff"]:
if before is None and after is not None:
- return [ProtoEnumAdded(after)]
+ return [ProtoEnumAdded(parent, after)]
elif before is not None and after is None:
- return [ProtoEnumRemoved(before)]
+ return [ProtoEnumRemoved(parent, before)]
elif before is None and after is None:
return []
elif before.name != after.name:
@@ -336,42 +340,51 @@ def diff(before: "ProtoEnum", after: "ProtoEnum") -> list["ProtoNodeDiff"]:
return []
diffs: list[ProtoNodeDiff] = []
# TODO: scope these diffs under ProtoEnum
- diffs.extend(ProtoOption.diff_sets(before.options, after.options))
+ diffs.extend(ProtoOption.diff_sets(parent, before.options, after.options))
diffs.extend(ProtoEnumValue.diff_sets(before, before.values, after.values))
return diffs
@staticmethod
def diff_sets(
- before: list["ProtoEnum"], after: list["ProtoEnum"]
+ parent: ProtoNode, before: list["ProtoEnum"], after: list["ProtoEnum"]
) -> list["ProtoNodeDiff"]:
diffs: list[ProtoNodeDiff] = []
before_names = set(o.name.identifier for o in before)
after_names = set(o.name.identifier for o in after)
for name in before_names - after_names:
diffs.append(
- ProtoEnumRemoved(next(i for i in before if i.name.identifier == name))
+ ProtoEnumRemoved(
+ parent, next(i for i in before if i.name.identifier == name)
+ )
)
for name in after_names - before_names:
diffs.append(
- ProtoEnumAdded(next(i for i in after if i.name.identifier == name))
+ ProtoEnumAdded(
+ parent, next(i for i in after if i.name.identifier == name)
+ )
)
for name in before_names & after_names:
before_enum = next(i for i in before if i.name.identifier == name)
after_enum = next(i for i in after if i.name.identifier == name)
- diffs.extend(ProtoEnum.diff(before_enum, after_enum))
+ diffs.extend(ProtoEnum.diff(parent, before_enum, after_enum))
return diffs
class ProtoEnumDiff(ProtoNodeDiff):
- def __init__(self, enum: ProtoEnum):
+ def __init__(self, parent: ProtoNode, enum: ProtoEnum):
+ self.parent = parent
self.enum = enum
def __eq__(self, other: object) -> bool:
- return isinstance(other, ProtoEnumDiff) and self.enum == other.enum
+ return (
+ isinstance(other, ProtoEnumDiff)
+ and self.parent == other.parent
+ and self.enum == other.enum
+ )
def __str__(self) -> str:
- return f"<{self.__class__.__name__} enum={self.enum}>"
+ return f"<{self.__class__.__name__} enum={self.enum} parent={self.parent}>"
class ProtoEnumAdded(ProtoEnumDiff):
@@ -382,9 +395,9 @@ class ProtoEnumRemoved(ProtoEnumDiff):
pass
-class ProtoEnumValueDiff(ProtoEnumDiff):
+class ProtoEnumValueDiff(ProtoNodeDiff):
def __init__(self, enum: "ProtoEnum", enum_value: "ProtoEnumValue"):
- super().__init__(enum)
+ self.enum = enum
self.enum_value = enum_value
def __eq__(self, other: object) -> bool:
diff --git a/src/proto_file.py b/src/proto_file.py
index a5bdd46..0b72760 100644
--- a/src/proto_file.py
+++ b/src/proto_file.py
@@ -151,7 +151,7 @@ def diff(self, other: "ProtoFile") -> Sequence[ProtoNodeDiff]:
diffs.extend(ProtoSyntax.diff(self.syntax, other.syntax))
diffs.extend(ProtoImport.diff_sets(self.imports, other.imports))
diffs.extend(ProtoPackage.diff(self.package, other.package))
- diffs.extend(ProtoEnum.diff_sets(self.enums, other.enums))
- diffs.extend(ProtoMessage.diff_sets(self.messages, other.messages))
+ diffs.extend(ProtoEnum.diff_sets(self, self.enums, other.enums))
+ diffs.extend(ProtoMessage.diff_sets(self, self.messages, other.messages))
return [d for d in diffs if d is not None]
diff --git a/src/proto_message.py b/src/proto_message.py
index 5cc85be..8776aaf 100644
--- a/src/proto_message.py
+++ b/src/proto_message.py
@@ -165,6 +165,10 @@ def maps(self) -> list[ProtoMap]:
def message_fields(self) -> list[ProtoMessageField]:
return [node for node in self.nodes if isinstance(node, ProtoMessageField)]
+ @property
+ def oneofs(self) -> list[ProtoOneOf]:
+ return [node for node in self.nodes if isinstance(node, ProtoOneOf)]
+
def serialize(self) -> str:
serialize_parts = (
[f"message {self.name.serialize()} {{"]
@@ -175,12 +179,14 @@ def serialize(self) -> str:
@staticmethod
def diff(
- before: "ProtoMessage", after: "ProtoMessage"
+ parent: ProtoNode,
+ before: "ProtoMessage",
+ after: "ProtoMessage",
) -> Sequence["ProtoNodeDiff"]:
if before is None and after is not None:
- return [ProtoMessageAdded(after)]
+ return [ProtoMessageAdded(parent, after)]
elif before is not None and after is None:
- return [ProtoMessageRemoved(before)]
+ return [ProtoMessageRemoved(parent, before)]
elif before is None and after is None:
return []
elif before.name != after.name:
@@ -188,8 +194,15 @@ def diff(
elif before == after:
return []
diffs: list[ProtoNodeDiff] = []
- diffs.extend(ProtoOption.diff_sets(before.options, after.options))
- # diffs.extend(ProtoOneOf.diff_sets(before, before.oneofs, after.oneofs))
+
+ # TODO:
+ # ProtoEnum,
+ # ProtoExtend,
+ # ProtoExtensions,
+ # ProtoMessage,
+ # ProtoReserved,
+ diffs.extend(ProtoOption.diff_sets(before, before.options, after.options))
+ diffs.extend(ProtoOneOf.diff_sets(before, before.oneofs, after.oneofs))
diffs.extend(ProtoMap.diff_sets(before, before.maps, after.maps))
diffs.extend(
ProtoMessageField.diff_sets(
@@ -200,7 +213,9 @@ def diff(
@staticmethod
def diff_sets(
- before: list["ProtoMessage"], after: list["ProtoMessage"]
+ parent: ProtoNode,
+ before: list["ProtoMessage"],
+ after: list["ProtoMessage"],
) -> Sequence["ProtoNodeDiff"]:
diffs: list[ProtoNodeDiff] = []
before_names = set(o.name.identifier for o in before)
@@ -208,30 +223,40 @@ def diff_sets(
for name in before_names - after_names:
diffs.append(
ProtoMessageRemoved(
- next(i for i in before if i.name.identifier == name)
+ parent,
+ next(i for i in before if i.name.identifier == name),
)
)
for name in after_names - before_names:
diffs.append(
- ProtoMessageAdded(next(i for i in after if i.name.identifier == name))
+ ProtoMessageAdded(
+ parent, next(i for i in after if i.name.identifier == name)
+ )
)
for name in before_names & after_names:
- before_enum = next(i for i in before if i.name.identifier == name)
- after_enum = next(i for i in after if i.name.identifier == name)
- diffs.extend(ProtoMessage.diff(before_enum, after_enum))
+ before_message = next(i for i in before if i.name.identifier == name)
+ after_message = next(i for i in after if i.name.identifier == name)
+ diffs.extend(ProtoMessage.diff(parent, before_message, after_message))
return diffs
class ProtoMessageDiff(ProtoNodeDiff):
- def __init__(self, message: ProtoMessage):
+ def __init__(self, parent: ProtoNode, message: ProtoMessage):
+ self.parent = parent
self.message = message
def __eq__(self, other: object) -> bool:
- return isinstance(other, ProtoMessageDiff) and self.message == other.message
+ return (
+ isinstance(other, ProtoMessageDiff)
+ and self.message == other.message
+ and self.parent == other.parent
+ )
def __str__(self) -> str:
- return f"<{self.__class__.__name__} message={self.message}>"
+ return (
+ f"<{self.__class__.__name__} message={self.message} parent={self.parent}>"
+ )
class ProtoMessageAdded(ProtoMessageDiff):
diff --git a/src/proto_message_field.py b/src/proto_message_field.py
index 2c3c749..1046646 100644
--- a/src/proto_message_field.py
+++ b/src/proto_message_field.py
@@ -264,7 +264,7 @@ def diff(
f"Don't know how to handle diff between message fields whose names are identical: {before}, {after}"
)
diffs.extend(
- ProtoMessageFieldOption.diff_sets(before.options, after.options)
+ ProtoMessageFieldOption.diff_sets(before, before.options, after.options)
)
return diffs
diff --git a/src/proto_oneof.py b/src/proto_oneof.py
index 5e225ab..b71c264 100644
--- a/src/proto_oneof.py
+++ b/src/proto_oneof.py
@@ -10,7 +10,7 @@
from src.proto_identifier import ProtoIdentifier
from src.proto_map import ProtoMap
from src.proto_message_field import ParsedProtoMessageFieldNode, ProtoMessageField
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
from src.proto_option import ParsedProtoOptionNode, ProtoOption
ProtoOneOfNodeTypes = (
@@ -151,6 +151,10 @@ def match(
def options(self) -> list[ProtoOption]:
return [node for node in self.nodes if isinstance(node, ProtoOption)]
+ @property
+ def message_fields(self) -> list[ProtoMessageField]:
+ return [node for node in self.nodes if isinstance(node, ProtoMessageField)]
+
def serialize(self) -> str:
serialize_parts = (
[f"oneof {self.name.serialize()} {{"]
@@ -158,3 +162,80 @@ def serialize(self) -> str:
+ ["}"]
)
return "\n".join(serialize_parts)
+
+ @staticmethod
+ def diff(
+ parent: ProtoNode, before: "ProtoOneOf", after: "ProtoOneOf"
+ ) -> Sequence["ProtoNodeDiff"]:
+ if before is None and after is not None:
+ return [ProtoOneOfAdded(parent, after)]
+ elif before is not None and after is None:
+ return [ProtoOneOfRemoved(parent, before)]
+ elif before is None and after is None:
+ return []
+ elif before.name != after.name:
+ return []
+ elif before == after:
+ return []
+ diffs: list[ProtoNodeDiff] = []
+ diffs.extend(ProtoOption.diff_sets(before, before.options, after.options))
+ diffs.extend(
+ ProtoMessageField.diff_sets(
+ before, before.message_fields, after.message_fields
+ )
+ )
+ return diffs
+
+ @staticmethod
+ def diff_sets(
+ parent: ProtoNode,
+ before: list["ProtoOneOf"],
+ after: list["ProtoOneOf"],
+ ) -> Sequence["ProtoNodeDiff"]:
+ diffs: list[ProtoNodeDiff] = []
+ before_names = set(o.name.identifier for o in before)
+ after_names = set(o.name.identifier for o in after)
+ for name in before_names - after_names:
+ diffs.append(
+ ProtoOneOfRemoved(
+ parent, next(i for i in before if i.name.identifier == name)
+ )
+ )
+ for name in after_names - before_names:
+ diffs.append(
+ ProtoOneOfAdded(
+ parent, next(i for i in after if i.name.identifier == name)
+ )
+ )
+ for name in before_names & after_names:
+ before_oneof = next(i for i in before if i.name.identifier == name)
+ after_oneof = next(i for i in after if i.name.identifier == name)
+ diffs.extend(ProtoOneOf.diff(parent, before_oneof, after_oneof))
+
+ return diffs
+
+
+class ProtoOneOfDiff(ProtoNodeDiff):
+ def __init__(self, parent: ProtoNode, oneof: ProtoOneOf):
+ self.parent = parent
+ self.oneof = oneof
+
+ def __eq__(self, other: object) -> bool:
+ return (
+ isinstance(other, ProtoOneOfDiff)
+ and self.oneof == other.oneof
+ and self.parent == other.parent
+ )
+
+ def __str__(self) -> str:
+ return f"<{self.__class__.__name__} oneof={self.oneof} parent={self.parent}>"
+
+
+class ProtoOneOfAdded(ProtoOneOfDiff):
+ def __eq__(self, other: object) -> bool:
+ return super().__eq__(other) and isinstance(other, ProtoOneOfAdded)
+
+
+class ProtoOneOfRemoved(ProtoOneOfDiff):
+ def __eq__(self, other: object) -> bool:
+ return super().__eq__(other) and isinstance(other, ProtoOneOfRemoved)
diff --git a/src/proto_option.py b/src/proto_option.py
index 2d07312..6ba48d2 100644
--- a/src/proto_option.py
+++ b/src/proto_option.py
@@ -124,39 +124,47 @@ def serialize(self) -> str:
@staticmethod
def diff(
- before: "ProtoOption", after: "ProtoOption"
+ parent: ProtoNode,
+ before: "ProtoOption",
+ after: "ProtoOption",
) -> Sequence["ProtoOptionDiff"]:
if before is None and after is not None:
- return [ProtoOptionAdded(after)]
+ return [ProtoOptionAdded(parent, after)]
elif before is not None and after is None:
- return [ProtoOptionRemoved(before)]
+ return [ProtoOptionRemoved(parent, before)]
elif before is None and after is None:
return []
elif before.name != after.name:
return []
elif before == after:
return []
- return [ProtoOptionValueChanged(before.name, before.value, after.value)]
+ return [ProtoOptionValueChanged(parent, before.name, before.value, after.value)]
@staticmethod
def diff_sets(
- before: Sequence["ProtoOption"], after: Sequence["ProtoOption"]
+ parent: ProtoNode,
+ before: Sequence["ProtoOption"],
+ after: Sequence["ProtoOption"],
) -> list["ProtoOptionDiff"]:
diffs: list[ProtoOptionDiff] = []
before_names = set(o.name.identifier for o in before)
after_names = set(o.name.identifier for o in after)
for name in before_names - after_names:
diffs.append(
- ProtoOptionRemoved(next(i for i in before if i.name.identifier == name))
+ ProtoOptionRemoved(
+ parent, next(i for i in before if i.name.identifier == name)
+ )
)
for name in after_names - before_names:
diffs.append(
- ProtoOptionAdded(next(i for i in after if i.name.identifier == name))
+ ProtoOptionAdded(
+ parent, next(i for i in after if i.name.identifier == name)
+ )
)
for name in before_names & after_names:
before_option = next(i for i in before if i.name.identifier == name)
after_option = next(i for i in after if i.name.identifier == name)
- diffs.extend(ProtoOption.diff(before_option, after_option))
+ diffs.extend(ProtoOption.diff(parent, before_option, after_option))
return diffs
@@ -167,11 +175,16 @@ class ProtoOptionDiff(ProtoNodeDiff):
class ProtoOptionValueChanged(ProtoOptionDiff):
def __init__(
- self, name: ProtoIdentifier, before: ProtoConstant, after: ProtoConstant
+ self,
+ parent: ProtoNode,
+ name: ProtoIdentifier,
+ before: ProtoConstant,
+ after: ProtoConstant,
):
self.name = name
self.before = before
self.after = after
+ self.parent = parent
def __eq__(self, other: object) -> bool:
return (
@@ -179,29 +192,40 @@ def __eq__(self, other: object) -> bool:
and self.name == other.name
and self.before == other.before
and self.after == other.after
+ and self.parent == other.parent
)
def __str__(self) -> str:
- return f""
+ return f""
class ProtoOptionAdded(ProtoOptionDiff):
- def __init__(self, before: ProtoOption):
+ def __init__(self, parent: ProtoNode, before: ProtoOption):
+ self.parent = parent
self.before = before
def __eq__(self, other: object) -> bool:
- return isinstance(other, ProtoOptionAdded) and self.before == other.before
+ return (
+ isinstance(other, ProtoOptionAdded)
+ and self.before == other.before
+ and self.parent == other.parent
+ )
def __str__(self) -> str:
- return f""
+ return f""
class ProtoOptionRemoved(ProtoOptionDiff):
- def __init__(self, after: ProtoOption):
+ def __init__(self, parent: ProtoNode, after: ProtoOption):
+ self.parent = parent
self.after = after
def __eq__(self, other: object) -> bool:
- return isinstance(other, ProtoOptionRemoved) and self.after == other.after
+ return (
+ isinstance(other, ProtoOptionRemoved)
+ and self.after == other.after
+ and self.parent == other.parent
+ )
def __str__(self) -> str:
- return f""
+ return f""
diff --git a/test/proto_enum_test.py b/test/proto_enum_test.py
index 237aabc..3463a6b 100644
--- a/test/proto_enum_test.py
+++ b/test/proto_enum_test.py
@@ -24,6 +24,7 @@
class EnumTest(unittest.TestCase):
maxDiff = None
+ DEFAULT_PARENT = ProtoEnum(ProtoIdentifier("DefaultParent"), [])
def test_enum_all_features(self):
parsed_enum_multiple_values = ProtoEnum.match(
@@ -333,7 +334,7 @@ def test_diff_same_enum_returns_empty(self):
ProtoIdentifier("MyEnum"),
[],
)
- self.assertEqual(ProtoEnum.diff(pe1, pe2), [])
+ self.assertEqual(ProtoEnum.diff(self.DEFAULT_PARENT, pe1, pe2), [])
def test_diff_different_enum_name_returns_empty(self):
pe1 = ProtoEnum(
@@ -344,7 +345,7 @@ def test_diff_different_enum_name_returns_empty(self):
ProtoIdentifier("OtherEnum"),
[],
)
- self.assertEqual(ProtoEnum.diff(pe1, pe2), [])
+ self.assertEqual(ProtoEnum.diff(self.DEFAULT_PARENT, pe1, pe2), [])
def test_diff_different_enum_value_name_returns_enum_diff(self):
pe1 = ProtoEnum(
@@ -373,7 +374,7 @@ def test_diff_different_enum_value_name_returns_enum_diff(self):
ProtoIdentifier("ME_KNOWN"),
)
],
- ProtoEnum.diff(pe1, pe2),
+ ProtoEnum.diff(self.DEFAULT_PARENT, pe1, pe2),
)
def test_diff_different_enum_value_value_returns_enum_diff(self):
@@ -396,7 +397,7 @@ def test_diff_different_enum_value_value_returns_enum_diff(self):
],
)
- diff = ProtoEnum.diff(pe1, pe2)
+ diff = ProtoEnum.diff(self.DEFAULT_PARENT, pe1, pe2)
self.assertIn(
ProtoEnumValueRemoved(
@@ -426,9 +427,10 @@ def test_diff_enum_added(self):
],
)
self.assertEqual(
- ProtoEnum.diff(pe1, pe2),
+ ProtoEnum.diff(self.DEFAULT_PARENT, pe1, pe2),
[
ProtoEnumAdded(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("MyEnum"),
[
@@ -437,7 +439,7 @@ def test_diff_enum_added(self):
ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
- )
+ ),
),
],
)
@@ -454,9 +456,10 @@ def test_diff_enum_removed(self):
)
pe2 = None
self.assertEqual(
- ProtoEnum.diff(pe1, pe2),
+ ProtoEnum.diff(self.DEFAULT_PARENT, pe1, pe2),
[
ProtoEnumRemoved(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("MyEnum"),
[
@@ -465,7 +468,7 @@ def test_diff_enum_removed(self):
ProtoInt(0, ProtoIntSign.POSITIVE),
)
],
- )
+ ),
),
],
)
@@ -473,7 +476,7 @@ def test_diff_enum_removed(self):
def test_diff_sets_empty_returns_empty(self):
set1 = []
set2 = []
- self.assertEqual(ProtoEnum.diff_sets(set1, set2), [])
+ self.assertEqual(ProtoEnum.diff_sets(self.DEFAULT_PARENT, set1, set2), [])
def test_diff_sets_no_change(self):
set1 = [
@@ -505,7 +508,7 @@ def test_diff_sets_no_change(self):
],
),
]
- self.assertEqual(ProtoEnum.diff_sets(set1, set1), [])
+ self.assertEqual(ProtoEnum.diff_sets(self.DEFAULT_PARENT, set1, set1), [])
def test_diff_sets_all_removed(self):
set1 = []
@@ -538,10 +541,11 @@ def test_diff_sets_all_removed(self):
],
),
]
- diff = ProtoEnum.diff_sets(set1, set2)
+ diff = ProtoEnum.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
ProtoEnumRemoved(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("FooEnum"),
[
@@ -556,6 +560,7 @@ def test_diff_sets_all_removed(self):
)
self.assertIn(
ProtoEnumRemoved(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("BarEnum"),
[
@@ -570,6 +575,7 @@ def test_diff_sets_all_removed(self):
)
self.assertIn(
ProtoEnumRemoved(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("TagEnum"),
[
@@ -615,10 +621,11 @@ def test_diff_sets_all_added(self):
),
]
set2 = []
- diff = ProtoEnum.diff_sets(set1, set2)
+ diff = ProtoEnum.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
ProtoEnumAdded(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("FooEnum"),
[
@@ -633,6 +640,7 @@ def test_diff_sets_all_added(self):
)
self.assertIn(
ProtoEnumAdded(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("BarEnum"),
[
@@ -647,6 +655,7 @@ def test_diff_sets_all_added(self):
)
self.assertIn(
ProtoEnumAdded(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("TagEnum"),
[
@@ -721,10 +730,11 @@ def test_diff_sets_mutually_exclusive(self):
),
]
- diff = ProtoEnum.diff_sets(set1, set2)
+ diff = ProtoEnum.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
ProtoEnumAdded(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("FooEnum"),
[
@@ -739,6 +749,7 @@ def test_diff_sets_mutually_exclusive(self):
)
self.assertIn(
ProtoEnumAdded(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("BarEnum"),
[
@@ -754,6 +765,7 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumAdded(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("TagEnum"),
[
@@ -769,6 +781,7 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumRemoved(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("FooEnum2"),
[
@@ -784,6 +797,7 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumRemoved(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("BarEnum2"),
[
@@ -799,6 +813,7 @@ def test_diff_sets_mutually_exclusive(self):
self.assertIn(
ProtoEnumRemoved(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("TagEnum2"),
[
@@ -874,10 +889,11 @@ def test_diff_sets_overlap(self):
),
]
- diff = ProtoEnum.diff_sets(set1, set2)
+ diff = ProtoEnum.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
ProtoEnumRemoved(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("FooEnum"),
[
@@ -893,6 +909,7 @@ def test_diff_sets_overlap(self):
self.assertIn(
ProtoEnumRemoved(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("TagEnum"),
[
@@ -907,6 +924,7 @@ def test_diff_sets_overlap(self):
)
self.assertIn(
ProtoEnumAdded(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("FooEnum2"),
[
@@ -921,6 +939,7 @@ def test_diff_sets_overlap(self):
)
self.assertIn(
ProtoEnumAdded(
+ self.DEFAULT_PARENT,
ProtoEnum(
ProtoIdentifier("TagEnum2"),
[
diff --git a/test/proto_message_test.py b/test/proto_message_test.py
index 1eae4f6..963adfc 100644
--- a/test/proto_message_test.py
+++ b/test/proto_message_test.py
@@ -30,6 +30,8 @@
class MessageTest(unittest.TestCase):
maxDiff = None
+ DEFAULT_PARENT = ProtoMessage(ProtoIdentifier("DefaultParent"), [])
+
def test_message_all_features(self):
parsed_message_multiple_fields = ProtoMessage.match(
dedent(
@@ -518,7 +520,7 @@ def test_diff_same_message_returns_empty(self):
ProtoIdentifier("MyMessage"),
[],
)
- self.assertEqual(ProtoMessage.diff(pm1, pm2), [])
+ self.assertEqual(ProtoMessage.diff(self.DEFAULT_PARENT, pm1, pm2), [])
def test_diff_different_message_name_returns_empty(self):
pm1 = ProtoMessage(
@@ -529,15 +531,17 @@ def test_diff_different_message_name_returns_empty(self):
ProtoIdentifier("OtherMessage"),
[],
)
- self.assertEqual(ProtoMessage.diff(pm1, pm2), [])
+ self.assertEqual(ProtoMessage.diff(self.DEFAULT_PARENT, pm1, pm2), [])
- def test_diff_enum_added(self):
+ def test_diff_message_added(self):
pm1 = None
pm2 = ProtoMessage(ProtoIdentifier("MyMessage"), [])
self.assertEqual(
- ProtoMessage.diff(pm1, pm2),
+ ProtoMessage.diff(self.DEFAULT_PARENT, pm1, pm2),
[
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("MyMessage"), [])),
+ ProtoMessageAdded(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("MyMessage"), [])
+ ),
],
)
@@ -545,16 +549,18 @@ def test_diff_message_removed(self):
pm1 = ProtoMessage(ProtoIdentifier("MyMessage"), [])
pm2 = None
self.assertEqual(
- ProtoMessage.diff(pm1, pm2),
+ ProtoMessage.diff(self.DEFAULT_PARENT, pm1, pm2),
[
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("MyMessage"), [])),
+ ProtoMessageRemoved(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("MyMessage"), [])
+ ),
],
)
def test_diff_sets_empty_returns_empty(self):
set1 = []
set2 = []
- self.assertEqual(ProtoMessage.diff_sets(set1, set2), [])
+ self.assertEqual(ProtoMessage.diff_sets(self.DEFAULT_PARENT, set1, set2), [])
def test_diff_sets_no_change_returns_empty(self):
set1 = [
@@ -562,7 +568,7 @@ def test_diff_sets_no_change_returns_empty(self):
ProtoMessage(ProtoIdentifier("BarMessage"), []),
ProtoMessage(ProtoIdentifier("BazMessage"), []),
]
- self.assertEqual(ProtoMessage.diff_sets(set1, set1), [])
+ self.assertEqual(ProtoMessage.diff_sets(self.DEFAULT_PARENT, set1, set1), [])
def test_diff_sets_all_removed(self):
set1 = [
@@ -571,17 +577,23 @@ def test_diff_sets_all_removed(self):
ProtoMessage(ProtoIdentifier("BazMessage"), []),
]
set2 = []
- diff = ProtoMessage.diff_sets(set1, set2)
+ diff = ProtoMessage.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage"), [])),
+ ProtoMessageRemoved(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("FooMessage"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BarMessage"), [])),
+ ProtoMessageRemoved(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BarMessage"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage"), [])),
+ ProtoMessageRemoved(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BazMessage"), [])
+ ),
diff,
)
self.assertEqual(3, len(diff))
@@ -594,17 +606,23 @@ def test_diff_sets_all_added(self):
ProtoMessage(ProtoIdentifier("BazMessage"), []),
]
- diff = ProtoMessage.diff_sets(set1, set2)
+ diff = ProtoMessage.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage"), [])),
+ ProtoMessageAdded(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("FooMessage"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BarMessage"), [])),
+ ProtoMessageAdded(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BarMessage"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage"), [])),
+ ProtoMessageAdded(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BazMessage"), [])
+ ),
diff,
)
self.assertEqual(3, len(diff))
@@ -620,29 +638,41 @@ def test_diff_sets_mutually_exclusive(self):
ProtoMessage(ProtoIdentifier("BarMessage2"), []),
ProtoMessage(ProtoIdentifier("BazMessage2"), []),
]
- diff = ProtoMessage.diff_sets(set1, set2)
+ diff = ProtoMessage.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage2"), [])),
+ ProtoMessageAdded(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("FooMessage2"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BarMessage2"), [])),
+ ProtoMessageAdded(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BarMessage2"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage2"), [])),
+ ProtoMessageAdded(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BazMessage2"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage"), [])),
+ ProtoMessageRemoved(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("FooMessage"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BarMessage"), [])),
+ ProtoMessageRemoved(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BarMessage"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage"), [])),
+ ProtoMessageRemoved(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BazMessage"), [])
+ ),
diff,
)
self.assertEqual(6, len(diff))
@@ -659,21 +689,29 @@ def test_diff_sets_overlap(self):
ProtoMessage(ProtoIdentifier("BarMessage"), []),
ProtoMessage(ProtoIdentifier("BazMessage2"), []),
]
- diff = ProtoMessage.diff_sets(set1, set2)
+ diff = ProtoMessage.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("FooMessage2"), [])),
+ ProtoMessageAdded(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("FooMessage2"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageAdded(ProtoMessage(ProtoIdentifier("BazMessage2"), [])),
+ ProtoMessageAdded(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BazMessage2"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("FooMessage"), [])),
+ ProtoMessageRemoved(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("FooMessage"), [])
+ ),
diff,
)
self.assertIn(
- ProtoMessageRemoved(ProtoMessage(ProtoIdentifier("BazMessage"), [])),
+ ProtoMessageRemoved(
+ self.DEFAULT_PARENT, ProtoMessage(ProtoIdentifier("BazMessage"), [])
+ ),
diff,
)
self.assertEqual(4, len(diff))
diff --git a/test/proto_oneof_test.py b/test/proto_oneof_test.py
index 0f0eec3..fbcb350 100644
--- a/test/proto_oneof_test.py
+++ b/test/proto_oneof_test.py
@@ -7,10 +7,13 @@
from src.proto_int import ProtoInt, ProtoIntSign
from src.proto_message_field import (
ProtoMessageField,
+ ProtoMessageFieldAdded,
+ ProtoMessageFieldNameChanged,
ProtoMessageFieldOption,
+ ProtoMessageFieldRemoved,
ProtoMessageFieldTypesEnum,
)
-from src.proto_oneof import ProtoOneOf
+from src.proto_oneof import ProtoOneOf, ProtoOneOfAdded, ProtoOneOfRemoved
from src.proto_option import ProtoOption
from src.proto_string_literal import ProtoStringLiteral
@@ -18,6 +21,11 @@
class OneOfTest(unittest.TestCase):
maxDiff = None
+ DEFAULT_PARENT = ProtoOneOf(
+ ProtoIdentifier("default_parent"),
+ [],
+ )
+
def test_oneof_empty(self):
parsed_oneof_empty = ProtoOneOf.match(dedent("oneof one_of_field {}".strip()))
self.assertEqual(
@@ -197,6 +205,255 @@ def test_oneof_normalize_removes_comment(self):
],
)
+ def test_diff_same_oneof_returns_empty(self):
+ po1 = ProtoOneOf(
+ ProtoIdentifier("my_one_of"),
+ [],
+ )
+ po2 = ProtoOneOf(
+ ProtoIdentifier("my_one_of"),
+ [],
+ )
+ self.assertEqual(ProtoOneOf.diff(self.DEFAULT_PARENT, po1, po2), [])
+
+ def test_diff_different_oneof_name_returns_empty(self):
+ po1 = ProtoOneOf(
+ ProtoIdentifier("my_one_of"),
+ [],
+ )
+ po2 = ProtoOneOf(
+ ProtoIdentifier("other_one_of"),
+ [],
+ )
+ self.assertEqual(ProtoOneOf.diff(self.DEFAULT_PARENT, po1, po2), [])
+
+ def test_diff_oneof_added(self):
+ po1 = None
+ po2 = ProtoOneOf(ProtoIdentifier("my_one_of"), [])
+ self.assertEqual(
+ ProtoOneOf.diff(self.DEFAULT_PARENT, po1, po2),
+ [
+ ProtoOneOfAdded(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("my_one_of"), [])
+ ),
+ ],
+ )
+
+ def test_diff_oneof_removed(self):
+ po1 = ProtoOneOf(ProtoIdentifier("my_one_of"), [])
+ po2 = None
+ self.assertEqual(
+ [
+ ProtoOneOfRemoved(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("my_one_of"), [])
+ ),
+ ],
+ ProtoOneOf.diff(self.DEFAULT_PARENT, po1, po2),
+ )
+
+ def test_diff_member_added(self):
+ po1 = ProtoOneOf(ProtoIdentifier("my_one_of"), [])
+ mf = ProtoMessageField(
+ ProtoMessageFieldTypesEnum.BOOL,
+ ProtoIdentifier("new_member"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
+ )
+ po2 = ProtoOneOf(ProtoIdentifier("my_one_of"), [mf])
+ self.assertEqual(
+ [ProtoMessageFieldAdded(po1, mf)],
+ ProtoOneOf.diff(self.DEFAULT_PARENT, po1, po2),
+ )
+
+ def test_diff_member_removed(self):
+ mf = ProtoMessageField(
+ ProtoMessageFieldTypesEnum.BOOL,
+ ProtoIdentifier("new_member"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
+ )
+ po1 = ProtoOneOf(ProtoIdentifier("my_one_of"), [mf])
+ po2 = ProtoOneOf(ProtoIdentifier("my_one_of"), [])
+ self.assertEqual(
+ [ProtoMessageFieldRemoved(po1, mf)],
+ ProtoOneOf.diff(self.DEFAULT_PARENT, po1, po2),
+ )
+
+ def test_diff_member_changed(self):
+ mf1 = ProtoMessageField(
+ ProtoMessageFieldTypesEnum.BOOL,
+ ProtoIdentifier("new_member"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
+ )
+ po1 = ProtoOneOf(ProtoIdentifier("my_one_of"), [mf1])
+ mf2 = ProtoMessageField(
+ ProtoMessageFieldTypesEnum.BOOL,
+ ProtoIdentifier("new_member_changed"),
+ ProtoInt(1, ProtoIntSign.POSITIVE),
+ )
+ po2 = ProtoOneOf(ProtoIdentifier("my_one_of"), [mf2])
+ self.assertEqual(
+ [ProtoMessageFieldNameChanged(po1, mf1, mf2.name)],
+ ProtoOneOf.diff(self.DEFAULT_PARENT, po1, po2),
+ )
+
+ def test_diff_sets_empty_returns_empty(self):
+ set1 = []
+ set2 = []
+ self.assertEqual(ProtoOneOf.diff_sets(self.DEFAULT_PARENT, set1, set2), [])
+
+ def test_diff_sets_no_change_returns_empty(self):
+ set1 = [
+ ProtoOneOf(ProtoIdentifier("foo_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("bar_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("baz_one_of"), []),
+ ]
+ self.assertEqual(ProtoOneOf.diff_sets(self.DEFAULT_PARENT, set1, set1), [])
+
+ def test_diff_sets_all_removed(self):
+ set1 = [
+ ProtoOneOf(ProtoIdentifier("foo_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("bar_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("baz_one_of"), []),
+ ]
+ set2 = []
+ diff = ProtoOneOf.diff_sets(self.DEFAULT_PARENT, set1, set2)
+ self.assertIn(
+ ProtoOneOfRemoved(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("foo_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfRemoved(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("bar_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfRemoved(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("baz_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_all_added(self):
+ set1 = []
+ set2 = [
+ ProtoOneOf(ProtoIdentifier("foo_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("bar_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("baz_one_of"), []),
+ ]
+
+ diff = ProtoOneOf.diff_sets(self.DEFAULT_PARENT, set1, set2)
+ self.assertIn(
+ ProtoOneOfAdded(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("foo_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfAdded(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("bar_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfAdded(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("baz_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertEqual(3, len(diff))
+
+ def test_diff_sets_mutually_exclusive(self):
+ set1 = [
+ ProtoOneOf(ProtoIdentifier("foo_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("bar_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("baz_one_of"), []),
+ ]
+ set2 = [
+ ProtoOneOf(ProtoIdentifier("foo_one_of2"), []),
+ ProtoOneOf(ProtoIdentifier("bar_one_of2"), []),
+ ProtoOneOf(ProtoIdentifier("baz_one_of2"), []),
+ ]
+ diff = ProtoOneOf.diff_sets(self.DEFAULT_PARENT, set1, set2)
+ self.assertIn(
+ ProtoOneOfAdded(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("foo_one_of2"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfAdded(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("bar_one_of2"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfAdded(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("baz_one_of2"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfRemoved(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("foo_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfRemoved(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("bar_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfRemoved(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("baz_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertEqual(6, len(diff))
+
+ def test_diff_sets_overlap(self):
+
+ set1 = [
+ ProtoOneOf(ProtoIdentifier("foo_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("bar_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("baz_one_of"), []),
+ ]
+ set2 = [
+ ProtoOneOf(ProtoIdentifier("foo_one_of2"), []),
+ ProtoOneOf(ProtoIdentifier("bar_one_of"), []),
+ ProtoOneOf(ProtoIdentifier("baz_one_of2"), []),
+ ]
+ diff = ProtoOneOf.diff_sets(self.DEFAULT_PARENT, set1, set2)
+ self.assertIn(
+ ProtoOneOfAdded(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("foo_one_of2"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfAdded(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("baz_one_of2"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfRemoved(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("foo_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertIn(
+ ProtoOneOfRemoved(
+ self.DEFAULT_PARENT, ProtoOneOf(ProtoIdentifier("baz_one_of"), [])
+ ),
+ diff,
+ )
+ self.assertEqual(4, len(diff))
+
if __name__ == "__main__":
unittest.main()
diff --git a/test/proto_option_test.py b/test/proto_option_test.py
index b6a90a2..f7a6a00 100644
--- a/test/proto_option_test.py
+++ b/test/proto_option_test.py
@@ -17,6 +17,10 @@
class OptionTest(unittest.TestCase):
maxDiff = None
+ DEFAULT_PARENT = ProtoOption(
+ ProtoIdentifier("default.parent"),
+ ProtoConstant(ProtoInt(1, ProtoIntSign.POSITIVE)),
+ )
def test_string_option(self):
string_option = ProtoOption.match("option foo = 'test value';")
@@ -215,7 +219,7 @@ def test_diff_same_option_returns_empty(self):
ProtoIdentifier("some.custom.option"),
ProtoConstant(ProtoStringLiteral("some value")),
)
- self.assertEqual(ProtoOption.diff(po1, po2), [])
+ self.assertEqual(ProtoOption.diff(self.DEFAULT_PARENT, po1, po2), [])
def test_diff_different_option_name_returns_empty(self):
po1 = ProtoOption(
@@ -226,7 +230,7 @@ def test_diff_different_option_name_returns_empty(self):
ProtoIdentifier("other.option"),
ProtoConstant(ProtoStringLiteral("some value")),
)
- self.assertEqual(ProtoOption.diff(po1, po2), [])
+ self.assertEqual(ProtoOption.diff(self.DEFAULT_PARENT, po1, po2), [])
def test_diff_different_option_value_returns_option_diff(self):
po1 = ProtoOption(
@@ -238,9 +242,10 @@ def test_diff_different_option_value_returns_option_diff(self):
ProtoConstant(ProtoStringLiteral("other value")),
)
self.assertEqual(
- ProtoOption.diff(po1, po2),
+ ProtoOption.diff(self.DEFAULT_PARENT, po1, po2),
[
ProtoOptionValueChanged(
+ self.DEFAULT_PARENT,
ProtoIdentifier("some.custom.option"),
ProtoConstant(ProtoStringLiteral("some value")),
ProtoConstant(ProtoStringLiteral("other value")),
@@ -255,13 +260,14 @@ def test_diff_option_added(self):
ProtoConstant(ProtoStringLiteral("some value")),
)
self.assertEqual(
- ProtoOption.diff(po1, po2),
+ ProtoOption.diff(self.DEFAULT_PARENT, po1, po2),
[
ProtoOptionAdded(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("some.custom.option"),
ProtoConstant(ProtoStringLiteral("some value")),
- )
+ ),
),
],
)
@@ -273,13 +279,14 @@ def test_diff_option_removed(self):
)
po2 = None
self.assertEqual(
- ProtoOption.diff(po1, po2),
+ ProtoOption.diff(self.DEFAULT_PARENT, po1, po2),
[
ProtoOptionRemoved(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("some.custom.option"),
ProtoConstant(ProtoStringLiteral("some value")),
- )
+ ),
),
],
)
@@ -287,7 +294,7 @@ def test_diff_option_removed(self):
def test_diff_sets_empty_returns_empty(self):
set1 = []
set2 = []
- self.assertEqual(ProtoOption.diff_sets(set1, set2), [])
+ self.assertEqual(ProtoOption.diff_sets(self.DEFAULT_PARENT, set1, set2), [])
def test_diff_sets_no_change(self):
set1 = [
@@ -304,7 +311,7 @@ def test_diff_sets_no_change(self):
ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
),
]
- self.assertEqual(ProtoOption.diff_sets(set1, set1), [])
+ self.assertEqual(ProtoOption.diff_sets(self.DEFAULT_PARENT, set1, set1), [])
def test_diff_sets_all_removed(self):
set1 = [
@@ -322,32 +329,35 @@ def test_diff_sets_all_removed(self):
),
]
set2 = []
- diff = ProtoOption.diff_sets(set1, set2)
+ diff = ProtoOption.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
ProtoOptionRemoved(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("some.custom.option"),
ProtoConstant(ProtoStringLiteral("some value")),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionRemoved(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("java_package"),
ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionRemoved(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("other.option"),
ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
- )
+ ),
),
diff,
)
@@ -369,32 +379,35 @@ def test_diff_sets_all_added(self):
ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
),
]
- diff = ProtoOption.diff_sets(set1, set2)
+ diff = ProtoOption.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
ProtoOptionAdded(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("some.custom.option"),
ProtoConstant(ProtoStringLiteral("some value")),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionAdded(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("java_package"),
ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionAdded(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("other.option"),
ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
- )
+ ),
),
diff,
)
@@ -430,63 +443,69 @@ def test_diff_sets_mutually_exclusive(self):
),
]
- diff = ProtoOption.diff_sets(set1, set2)
+ diff = ProtoOption.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
ProtoOptionAdded(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("some.custom.option.but.not.prior"),
ProtoConstant(ProtoStringLiteral("some value")),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionAdded(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("other.option.but.stil.not.prior"),
ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionAdded(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("ruby_package"),
ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionRemoved(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("other.option"),
ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionRemoved(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("some.custom.option"),
ProtoConstant(ProtoStringLiteral("some value")),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionRemoved(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("java_package"),
ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
- )
+ ),
),
diff,
)
@@ -523,47 +542,52 @@ def test_diff_sets_overlap(self):
),
]
- diff = ProtoOption.diff_sets(set1, set2)
+ diff = ProtoOption.diff_sets(self.DEFAULT_PARENT, set1, set2)
self.assertIn(
ProtoOptionRemoved(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("some.custom.option"),
ProtoConstant(ProtoStringLiteral("some value")),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionRemoved(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("other.option"),
ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionAdded(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("some.custom.option.but.not.prior"),
ProtoConstant(ProtoStringLiteral("some value")),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionAdded(
+ self.DEFAULT_PARENT,
ProtoOption(
ProtoIdentifier("other.option.but.stil.not.prior"),
ProtoConstant(ProtoInt(100, ProtoIntSign.POSITIVE)),
- )
+ ),
),
diff,
)
self.assertIn(
ProtoOptionValueChanged(
+ self.DEFAULT_PARENT,
ProtoIdentifier("java_package"),
ProtoConstant(ProtoStringLiteral("foo.bar.baz")),
ProtoConstant(ProtoStringLiteral("foo.bar.bat")),
From f2049fdcfe9890125a7db2d52048385b30111472 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sat, 11 Mar 2023 01:47:11 -0400
Subject: [PATCH 23/35] Make generic proto container class (#80)
---
src/proto_enum.py | 74 +++++++++++--------------------
src/proto_extend.py | 68 +++++++++++------------------
src/proto_message.py | 91 +++++++++++++++-----------------------
src/proto_node.py | 102 ++++++++++++++++++++++++++++++++++++++++++-
src/proto_oneof.py | 99 +++++++++++++++++------------------------
src/proto_service.py | 84 +++++++++++++++--------------------
6 files changed, 264 insertions(+), 254 deletions(-)
diff --git a/src/proto_enum.py b/src/proto_enum.py
index a37bd07..986769a 100644
--- a/src/proto_enum.py
+++ b/src/proto_enum.py
@@ -5,10 +5,10 @@
ProtoMultiLineComment,
ProtoSingleLineComment,
)
-from src.proto_identifier import ProtoIdentifier
+from src.proto_identifier import ParsedProtoIdentifierNode, ProtoIdentifier
from src.proto_int import ProtoInt, ProtoIntSign
-from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
-from src.proto_option import ParsedProtoOptionNode, ProtoOption, ProtoOptionDiff
+from src.proto_node import ParsedProtoNode, ProtoContainerNode, ProtoNode, ProtoNodeDiff
+from src.proto_option import ParsedProtoOptionNode, ProtoOption
from src.proto_reserved import ProtoReserved
@@ -212,20 +212,17 @@ def diff_sets(
return diffs
-class ProtoEnum(ProtoNode):
- def __init__(self, name: ProtoIdentifier, nodes: list[ProtoNode], *args, **kwargs):
+class ProtoEnum(ProtoContainerNode):
+ def __init__(self, name: ProtoIdentifier, *args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
- self.nodes = nodes
- for option in self.options:
- option.parent = self
def __eq__(self, other: object) -> bool:
return (
isinstance(other, ProtoEnum)
+ and super().__eq__(other)
and self.name == other.name
- and self.nodes == other.nodes
)
def __str__(self) -> str:
@@ -244,34 +241,22 @@ def normalize(self) -> "ProtoEnum":
parent=self.parent,
)
- @staticmethod
- def parse_partial_content(partial_enum_content: str) -> ParsedProtoNode:
- supported_types: list[type[ProtoNode]] = [
+ @classmethod
+ def container_types(cls) -> list[type[ProtoNode]]:
+ return [
ProtoSingleLineComment,
ProtoMultiLineComment,
ProtoOption,
ProtoReserved,
ProtoEnumValue,
]
- for node_type in supported_types:
- try:
- match_result = node_type.match(
- proto_source=partial_enum_content, parent=None
- )
- except (ValueError, IndexError, TypeError):
- raise ValueError(
- f"Could not parse partial enum content:\n{partial_enum_content}"
- )
- if match_result is not None:
- return match_result
- raise ValueError(
- f"Could not parse partial enum content:\n{partial_enum_content}"
- )
@classmethod
- def match(
- cls, proto_source: str, parent: Optional[ProtoNode] = None
- ) -> Optional["ParsedProtoNode"]:
+ def match_header(
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
+ ) -> Optional["ParsedProtoIdentifierNode"]:
if not proto_source.startswith("enum "):
return None
@@ -288,25 +273,18 @@ def match(
f"Proto has invalid syntax, expecting opening curly brace: {proto_source}"
)
- proto_source = proto_source[1:].strip()
- parsed_tree = []
- while proto_source:
- # Remove empty statements.
- if proto_source.startswith(";"):
- proto_source = proto_source[1:].strip()
- continue
-
- if proto_source.startswith("}"):
- proto_source = proto_source[1:].strip()
- break
-
- match_result = ProtoEnum.parse_partial_content(proto_source)
- parsed_tree.append(match_result.node)
- proto_source = match_result.remaining_source.strip()
-
- return ParsedProtoNode(
- ProtoEnum(name=enum_name, nodes=parsed_tree, parent=parent), proto_source
- )
+ return ParsedProtoIdentifierNode(enum_name, proto_source[1:].strip())
+
+ @classmethod
+ def construct(
+ cls,
+ header_match: ParsedProtoNode,
+ contained_nodes: list[ProtoNode],
+ footer_match: str,
+ parent: Optional[ProtoNode] = None,
+ ) -> ProtoNode:
+ assert isinstance(header_match, ParsedProtoIdentifierNode)
+ return ProtoEnum(name=header_match.node, nodes=contained_nodes, parent=parent)
@property
def options(self) -> list[ProtoOption]:
diff --git a/src/proto_extend.py b/src/proto_extend.py
index ece3e23..007a942 100644
--- a/src/proto_extend.py
+++ b/src/proto_extend.py
@@ -5,28 +5,27 @@
ProtoMultiLineComment,
ProtoSingleLineComment,
)
-from src.proto_identifier import ProtoEnumOrMessageIdentifier
+from src.proto_identifier import (
+ ParsedProtoEnumOrMessageIdentifierNode,
+ ProtoEnumOrMessageIdentifier,
+)
from src.proto_message_field import ProtoMessageField
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_node import ParsedProtoNode, ProtoContainerNode, ProtoNode
-class ProtoExtend(ProtoNode):
+class ProtoExtend(ProtoContainerNode):
def __init__(
self,
name: ProtoEnumOrMessageIdentifier,
- nodes: list[ProtoNode],
*args,
**kwargs,
):
super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
- self.nodes = nodes
- for node in self.nodes:
- node.parent = self
def __eq__(self, other) -> bool:
- return self.name == other.name and self.nodes == other.nodes
+ return super().__eq__(other) and self.name == other.name
def __str__(self) -> str:
return f""
@@ -44,28 +43,20 @@ def normalize(self) -> "ProtoExtend":
parent=self.parent,
)
- @staticmethod
- def parse_partial_content(partial_content: str) -> ParsedProtoNode:
- supported_types: list[type[ProtoNode]] = [
+ @classmethod
+ def container_types(cls) -> list[type[ProtoNode]]:
+ return [
ProtoSingleLineComment,
ProtoMultiLineComment,
ProtoMessageField,
]
- for node_type in supported_types:
- try:
- match_result = node_type.match(partial_content)
- except (ValueError, IndexError, TypeError):
- raise ValueError(
- f"Could not parse partial extend content:\n{partial_content}"
- )
- if match_result is not None:
- return match_result
- raise ValueError(f"Could not parse partial extend content:\n{partial_content}")
@classmethod
- def match(
- cls, proto_source: str, parent: Optional[ProtoNode] = None
- ) -> Optional["ParsedProtoNode"]:
+ def match_header(
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
+ ) -> Optional["ParsedProtoEnumOrMessageIdentifierNode"]:
if not proto_source.startswith("extend "):
return None
@@ -82,25 +73,18 @@ def match(
f"Proto extend has invalid syntax, expecting opening curly brace: {proto_source}"
)
- proto_source = proto_source[1:].strip()
- parsed_tree = []
- while proto_source:
- # Remove empty statements.
- if proto_source.startswith(";"):
- proto_source = proto_source[1:].strip()
- continue
-
- if proto_source.startswith("}"):
- proto_source = proto_source[1:].strip()
- break
+ return ParsedProtoEnumOrMessageIdentifierNode(name, proto_source[1:].strip())
- match_result = ProtoExtend.parse_partial_content(proto_source)
- parsed_tree.append(match_result.node)
- proto_source = match_result.remaining_source.strip()
-
- return ParsedProtoNode(
- ProtoExtend(name=name, nodes=parsed_tree, parent=parent), proto_source
- )
+ @classmethod
+ def construct(
+ cls,
+ header_match: ParsedProtoNode,
+ contained_nodes: list[ProtoNode],
+ footer_match: str,
+ parent: Optional[ProtoNode] = None,
+ ) -> ProtoNode:
+ assert isinstance(header_match, ParsedProtoEnumOrMessageIdentifierNode)
+ return ProtoExtend(name=header_match.node, nodes=contained_nodes, parent=parent)
def serialize(self) -> str:
serialize_parts = (
diff --git a/src/proto_message.py b/src/proto_message.py
index 8776aaf..6e261c0 100644
--- a/src/proto_message.py
+++ b/src/proto_message.py
@@ -8,32 +8,28 @@
from src.proto_enum import ProtoEnum
from src.proto_extend import ProtoExtend
from src.proto_extensions import ProtoExtensions
-from src.proto_identifier import ProtoIdentifier
+from src.proto_identifier import ParsedProtoIdentifierNode, ProtoIdentifier
from src.proto_map import ProtoMap
from src.proto_message_field import ProtoMessageField
-from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
+from src.proto_node import ParsedProtoNode, ProtoContainerNode, ProtoNode, ProtoNodeDiff
from src.proto_oneof import ProtoOneOf
from src.proto_option import ProtoOption
from src.proto_reserved import ProtoReserved
-class ProtoMessage(ProtoNode):
+class ProtoMessage(ProtoContainerNode):
def __init__(
self,
name: ProtoIdentifier,
- nodes: Sequence[ProtoNode],
*args,
**kwargs,
):
super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
- self.nodes = nodes
- for node in self.nodes:
- node.parent = self
def __eq__(self, other) -> bool:
- return self.name == other.name and self.nodes == other.nodes
+ return super().__eq__(other) and self.name == other.name
def __str__(self) -> str:
return f""
@@ -85,38 +81,12 @@ def normalize(self) -> "ProtoMessage":
parent=self.parent,
)
- @staticmethod
- def parse_partial_content(partial_message_content: str) -> ParsedProtoNode:
- supported_types: list[type[ProtoNode]] = [
- ProtoSingleLineComment,
- ProtoMultiLineComment,
- ProtoEnum,
- ProtoExtend,
- ProtoExtensions,
- ProtoOption,
- ProtoMessage,
- ProtoReserved,
- ProtoMessageField,
- ProtoOneOf,
- ProtoMap,
- ]
- for node_type in supported_types:
- try:
- match_result = node_type.match(partial_message_content)
- except (ValueError, IndexError, TypeError):
- raise ValueError(
- f"Could not parse partial message content:\n{partial_message_content}"
- )
- if match_result is not None:
- return match_result
- raise ValueError(
- f"Could not parse partial message content:\n{partial_message_content}"
- )
-
@classmethod
- def match(
- cls, proto_source: str, parent: Optional[ProtoNode] = None
- ) -> Optional["ParsedProtoNode"]:
+ def match_header(
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
+ ) -> Optional["ParsedProtoIdentifierNode"]:
if not proto_source.startswith("message "):
return None
@@ -133,24 +103,35 @@ def match(
f"Proto message has invalid syntax, expecting opening curly brace: {proto_source}"
)
- proto_source = proto_source[1:].strip()
- parsed_tree = []
- while proto_source:
- # Remove empty statements.
- if proto_source.startswith(";"):
- proto_source = proto_source[1:].strip()
- continue
+ return ParsedProtoIdentifierNode(enum_name, proto_source[1:].strip())
- if proto_source.startswith("}"):
- proto_source = proto_source[1:].strip()
- break
-
- match_result = ProtoMessage.parse_partial_content(proto_source)
- parsed_tree.append(match_result.node)
- proto_source = match_result.remaining_source.strip()
+ @classmethod
+ def container_types(cls) -> list[type[ProtoNode]]:
+ return [
+ ProtoSingleLineComment,
+ ProtoMultiLineComment,
+ ProtoEnum,
+ ProtoExtend,
+ ProtoExtensions,
+ ProtoOption,
+ ProtoMessage,
+ ProtoReserved,
+ ProtoMessageField,
+ ProtoOneOf,
+ ProtoMap,
+ ]
- return ParsedProtoNode(
- ProtoMessage(name=enum_name, nodes=parsed_tree, parent=parent), proto_source
+ @classmethod
+ def construct(
+ cls,
+ header_match: ParsedProtoNode,
+ contained_nodes: list[ProtoNode],
+ footer_match: str,
+ parent: Optional[ProtoNode] = None,
+ ) -> ProtoNode:
+ assert isinstance(header_match, ParsedProtoIdentifierNode)
+ return ProtoMessage(
+ name=header_match.node, nodes=contained_nodes, parent=parent
)
@property
diff --git a/src/proto_node.py b/src/proto_node.py
index 5647cb6..f69c3f4 100644
--- a/src/proto_node.py
+++ b/src/proto_node.py
@@ -1,5 +1,5 @@
import abc
-from typing import NamedTuple, Optional
+from typing import NamedTuple, Optional, Sequence
class ProtoNode(abc.ABC):
@@ -24,6 +24,106 @@ def normalize(self) -> Optional["ProtoNode"]:
raise NotImplementedError
+class ProtoContainerNode(ProtoNode):
+ def __init__(
+ self,
+ nodes: Sequence[ProtoNode],
+ *args,
+ **kwargs,
+ ):
+ super().__init__(*args, **kwargs)
+ self.nodes = nodes
+ for node in self.nodes:
+ node.parent = self
+
+ def __eq__(self, other) -> bool:
+ return self.nodes == other.nodes
+
+ @classmethod
+ @abc.abstractmethod
+ def match_header(
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
+ ) -> Optional["ParsedProtoNode"]:
+ raise NotImplementedError
+
+ @classmethod
+ def match_footer(
+ cls,
+ proto_source: str,
+ parent: Optional[ProtoNode] = None,
+ ) -> Optional[str]:
+ if proto_source.startswith("}"):
+ return proto_source[1:].strip()
+
+ return None
+
+ @classmethod
+ @abc.abstractmethod
+ def container_types(cls) -> list[type[ProtoNode]]:
+ raise NotImplementedError
+
+ @classmethod
+ @abc.abstractmethod
+ def construct(
+ cls,
+ header_match: "ParsedProtoNode",
+ contained_nodes: list[ProtoNode],
+ footer_match: str,
+ parent: Optional[ProtoNode] = None,
+ ) -> ProtoNode:
+ raise NotImplementedError
+
+ @classmethod
+ def parse_partial_content(cls, partial_content: str) -> "ParsedProtoNode":
+ for node_type in cls.container_types():
+ try:
+ match_result = node_type.match(partial_content)
+ except (ValueError, IndexError, TypeError):
+ raise ValueError(f"Could not parse partial content:\n{partial_content}")
+ if match_result is not None:
+ return match_result
+ raise ValueError(f"Could not parse partial content:\n{partial_content}")
+
+ @classmethod
+ def match(
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
+ ) -> Optional["ParsedProtoNode"]:
+ header_match = cls.match_header(proto_source, parent=parent)
+ if header_match is None:
+ return None
+
+ proto_source = header_match.remaining_source.strip()
+ nodes = []
+ while proto_source:
+ # Remove empty statements.
+ if proto_source.startswith(";"):
+ proto_source = proto_source[1:].strip()
+ continue
+
+ footer_match = cls.match_footer(proto_source, parent)
+ if footer_match is not None:
+ proto_source = footer_match.strip()
+ break
+
+ match_result = cls.parse_partial_content(proto_source)
+ nodes.append(match_result.node)
+ proto_source = match_result.remaining_source.strip()
+
+ if footer_match is None:
+ raise ValueError(
+ f"Footer was not found when matching container node {cls} for remaining proto source {proto_source}"
+ )
+
+ return ParsedProtoNode(
+ cls.construct(header_match, nodes, footer_match, parent=parent),
+ proto_source.strip(),
+ )
+
+
class ParsedProtoNode(NamedTuple):
node: ProtoNode
remaining_source: str
diff --git a/src/proto_oneof.py b/src/proto_oneof.py
index b71c264..50493d3 100644
--- a/src/proto_oneof.py
+++ b/src/proto_oneof.py
@@ -7,10 +7,10 @@
ProtoMultiLineComment,
ProtoSingleLineComment,
)
-from src.proto_identifier import ProtoIdentifier
+from src.proto_identifier import ParsedProtoIdentifierNode, ProtoIdentifier
from src.proto_map import ProtoMap
from src.proto_message_field import ParsedProtoMessageFieldNode, ProtoMessageField
-from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
+from src.proto_node import ParsedProtoNode, ProtoContainerNode, ProtoNode, ProtoNodeDiff
from src.proto_option import ParsedProtoOptionNode, ProtoOption
ProtoOneOfNodeTypes = (
@@ -29,23 +29,19 @@ class ParsedProtoOneOfNode(ParsedProtoNode):
remaining_source: str
-class ProtoOneOf(ProtoNode):
+class ProtoOneOf(ProtoContainerNode):
def __init__(
self,
name: ProtoIdentifier,
- nodes: Sequence[ProtoOneOfNodeTypes],
*args,
**kwargs,
):
super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
- self.nodes = nodes
- for node in self.nodes:
- node.parent = self
def __eq__(self, other) -> bool:
- return self.name == other.name and self.nodes == other.nodes
+ return super().__eq__(other) and self.name == other.name
def __str__(self) -> str:
return f"<{self.__class__.__name__} name={self.name}, nodes={self.nodes}>"
@@ -58,56 +54,39 @@ def normalize(self) -> "ProtoOneOf":
lambda n: not isinstance(n, ProtoComment), self.nodes
)
options = []
- fields = []
+ fields: list[ProtoMessageField | ProtoMap] = []
+ oneofs: list[ProtoOneOf] = []
for node in non_comment_nodes:
if isinstance(node, ProtoOption):
options.append(node.normalize())
- elif (
- isinstance(node, ProtoMessageField)
- or isinstance(node, ProtoOneOf)
- or isinstance(node, ProtoMap)
- ):
+ elif isinstance(node, ProtoMessageField) or isinstance(node, ProtoMap):
fields.append(node.normalize())
+ elif isinstance(node, ProtoOneOf):
+ oneofs.append(node.normalize())
else:
raise ValueError(
f"Can't sort message {self} node for normalizing: {node}"
)
- sorted_nodes_for_normalizing = sorted(
- options, key=lambda o: str(o.normalize())
- ) + sorted(fields, key=lambda f: int(f.number))
+ sorted_options = sorted(options, key=lambda o: str(o.normalize()))
+ sorted_fields = sorted(fields, key=lambda f: int(f.number))
+ sorted_oneofs = sorted(
+ oneofs,
+ key=lambda x: min(int(f.number) for f in x.message_fields),
+ )
return ProtoOneOf(
name=self.name,
- nodes=sorted_nodes_for_normalizing,
+ nodes=(sorted_options + sorted_fields + sorted_oneofs),
parent=self.parent,
)
- @staticmethod
- def parse_partial_content(partial_oneof_content: str) -> ProtoParsedOneOfNodeTypes:
- supported_types: list[type[ProtoOneOfNodeTypes]] = [
- ProtoMessageField,
- ProtoOption,
- ProtoSingleLineComment,
- ProtoMultiLineComment,
- ]
- for node_type in supported_types:
- try:
- match_result = node_type.match(partial_oneof_content)
- except (ValueError, IndexError, TypeError):
- raise ValueError(
- f"Could not parse partial oneof content:\n{partial_oneof_content}"
- )
- if match_result is not None:
- return match_result
- raise ValueError(
- f"Could not parse partial oneof content:\n{partial_oneof_content}"
- )
-
@classmethod
- def match(
- cls, proto_source: str, parent: Optional[ProtoNode] = None
- ) -> Optional["ParsedProtoOneOfNode"]:
+ def match_header(
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
+ ) -> Optional["ParsedProtoIdentifierNode"]:
if not proto_source.startswith("oneof "):
return None
@@ -127,25 +106,27 @@ def match(
f"Proto has invalid syntax, expecting opening curly brace: {proto_source}"
)
- proto_source = proto_source[1:].strip()
- parsed_tree = []
- while proto_source:
- # Remove empty statements.
- if proto_source.startswith(";"):
- proto_source = proto_source[1:].strip()
- continue
-
- if proto_source.startswith("}"):
- proto_source = proto_source[1:].strip()
- break
+ return ParsedProtoIdentifierNode(oneof_name, proto_source[1:].strip())
- match_result = ProtoOneOf.parse_partial_content(proto_source)
- parsed_tree.append(match_result.node)
- proto_source = match_result.remaining_source.strip()
+ @classmethod
+ def container_types(cls) -> list[type[ProtoNode]]:
+ return [
+ ProtoMessageField,
+ ProtoOption,
+ ProtoSingleLineComment,
+ ProtoMultiLineComment,
+ ]
- return ParsedProtoOneOfNode(
- ProtoOneOf(name=oneof_name, nodes=parsed_tree, parent=parent), proto_source
- )
+ @classmethod
+ def construct(
+ cls,
+ header_match: ParsedProtoNode,
+ contained_nodes: list[ProtoNode],
+ footer_match: str,
+ parent: Optional[ProtoNode] = None,
+ ) -> ProtoNode:
+ assert isinstance(header_match, ParsedProtoIdentifierNode)
+ return ProtoOneOf(name=header_match.node, nodes=contained_nodes, parent=parent)
@property
def options(self) -> list[ProtoOption]:
diff --git a/src/proto_service.py b/src/proto_service.py
index d408849..26f7d17 100644
--- a/src/proto_service.py
+++ b/src/proto_service.py
@@ -5,8 +5,12 @@
ProtoMultiLineComment,
ProtoSingleLineComment,
)
-from src.proto_identifier import ProtoEnumOrMessageIdentifier, ProtoIdentifier
-from src.proto_node import ParsedProtoNode, ProtoNode
+from src.proto_identifier import (
+ ParsedProtoIdentifierNode,
+ ProtoEnumOrMessageIdentifier,
+ ProtoIdentifier,
+)
+from src.proto_node import ParsedProtoNode, ProtoContainerNode, ProtoNode
from src.proto_option import ProtoOption
@@ -218,17 +222,14 @@ def serialize(self) -> str:
return " ".join(serialized_parts) + ";"
-class ProtoService(ProtoNode):
- def __init__(self, name: ProtoIdentifier, nodes: list[ProtoNode], *args, **kwargs):
+class ProtoService(ProtoContainerNode):
+ def __init__(self, name: ProtoIdentifier, *args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.name.parent = self
- self.nodes = nodes
- for node in self.nodes:
- node.parent = self
def __eq__(self, other) -> bool:
- return self.name == other.name and self.nodes == other.nodes
+ return super().__eq__(other) and self.name == other.name
def __str__(self) -> str:
return f""
@@ -246,31 +247,12 @@ def normalize(self) -> "ProtoService":
parent=self.parent,
)
- @staticmethod
- def parse_partial_content(partial_service_content: str) -> ParsedProtoNode:
- supported_types: list[type[ProtoNode]] = [
- ProtoOption,
- ProtoServiceRPC,
- ProtoSingleLineComment,
- ProtoMultiLineComment,
- ]
- for node_type in supported_types:
- try:
- match_result = node_type.match(partial_service_content)
- except (ValueError, IndexError, TypeError):
- raise ValueError(
- f"Could not parse partial service content:\n{partial_service_content}"
- )
- if match_result is not None:
- return match_result
- raise ValueError(
- f"Could not parse partial service content:\n{partial_service_content}"
- )
-
@classmethod
- def match(
- cls, proto_source: str, parent: Optional[ProtoNode] = None
- ) -> Optional["ParsedProtoNode"]:
+ def match_header(
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
+ ) -> Optional["ParsedProtoIdentifierNode"]:
if not proto_source.startswith("service "):
return None
@@ -279,7 +261,7 @@ def match(
if match is None:
raise ValueError(f"Proto has invalid service name: {proto_source}")
- enum_name = match.node
+ service_name = match.node
proto_source = match.remaining_source.strip()
if not proto_source.startswith("{"):
@@ -287,24 +269,28 @@ def match(
f"Proto service has invalid syntax, expecting opening curly brace: {proto_source}"
)
- proto_source = proto_source[1:].strip()
- parsed_tree = []
- while proto_source:
- # Remove empty statements.
- if proto_source.startswith(";"):
- proto_source = proto_source[1:].strip()
- continue
-
- if proto_source.startswith("}"):
- proto_source = proto_source[1:].strip()
- break
+ return ParsedProtoIdentifierNode(service_name, proto_source[1:].strip())
- match_result = ProtoService.parse_partial_content(proto_source)
- parsed_tree.append(match_result.node)
- proto_source = match_result.remaining_source.strip()
+ @classmethod
+ def container_types(cls) -> list[type[ProtoNode]]:
+ return [
+ ProtoOption,
+ ProtoServiceRPC,
+ ProtoSingleLineComment,
+ ProtoMultiLineComment,
+ ]
- return ParsedProtoNode(
- ProtoService(name=enum_name, nodes=parsed_tree, parent=parent), proto_source
+ @classmethod
+ def construct(
+ cls,
+ header_match: ParsedProtoNode,
+ contained_nodes: list[ProtoNode],
+ footer_match: str,
+ parent: Optional[ProtoNode] = None,
+ ) -> ProtoNode:
+ assert isinstance(header_match, ParsedProtoIdentifierNode)
+ return ProtoService(
+ name=header_match.node, nodes=contained_nodes, parent=parent
)
@property
From 8aa68dcf7015e52a8c0edeb9bd8ccf6870f46c8b Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Sat, 11 Mar 2023 02:56:10 -0400
Subject: [PATCH 24/35] Make ProtoFile a container type (#81)
---
src/proto_file.py | 111 ++++++++++++++++++++++++++++++---------------
src/proto_node.py | 9 ++--
src/util/parser.py | 5 +-
3 files changed, 82 insertions(+), 43 deletions(-)
diff --git a/src/proto_file.py b/src/proto_file.py
index 0b72760..94d793a 100644
--- a/src/proto_file.py
+++ b/src/proto_file.py
@@ -9,7 +9,7 @@
from src.proto_extend import ProtoExtend
from src.proto_import import ProtoImport
from src.proto_message import ProtoMessage
-from src.proto_node import ParsedProtoNode, ProtoNode, ProtoNodeDiff
+from src.proto_node import ParsedProtoNode, ProtoContainerNode, ProtoNode, ProtoNodeDiff
from src.proto_option import ProtoOption
from src.proto_package import ProtoPackage
from src.proto_service import ProtoService
@@ -21,13 +21,40 @@ class ParsedProtoFileNode(ParsedProtoNode):
remaining_source: str
-class ProtoFile(ProtoNode):
- def __init__(self, syntax: ProtoSyntax, nodes: list[ProtoNode], *args, **kwargs):
+class ProtoFileHeaderNode(ProtoNode):
+ def __init__(
+ self, header_nodes: list[ProtoNode], syntax: ProtoSyntax, *args, **kwargs
+ ):
super().__init__(*args, **kwargs)
+ self.header_nodes = header_nodes
self.syntax = syntax
- self.nodes = nodes
- if len([node for node in nodes if isinstance(node, ProtoPackage)]) > 1:
+ @classmethod
+ def match(
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
+ ) -> Optional["ParsedProtoNode"]:
+ pass
+
+ def serialize(self) -> str:
+ raise NotImplementedError
+
+ def normalize(self) -> Optional["ProtoNode"]:
+ raise NotImplementedError
+
+
+class ParsedProtoFileHeaderNode(ParsedProtoNode):
+ node: "ProtoFileHeaderNode"
+ remaining_source: str
+
+
+class ProtoFile(ProtoContainerNode):
+ def __init__(self, syntax: ProtoSyntax, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.syntax = syntax
+
+ if len([node for node in self.nodes if isinstance(node, ProtoPackage)]) > 1:
raise ValueError(f"Proto can't have more than one package statement")
@property
@@ -53,9 +80,34 @@ def enums(self) -> list[ProtoEnum]:
def messages(self) -> list[ProtoMessage]:
return [node for node in self.nodes if isinstance(node, ProtoMessage)]
- @staticmethod
- def parse_partial_content(partial_proto_content: str) -> ParsedProtoNode:
- node_types: list[type[ProtoNode]] = [
+ @classmethod
+ def match_header(
+ cls,
+ proto_source: str,
+ parent: Optional["ProtoNode"] = None,
+ ) -> Optional["ParsedProtoNode"]:
+ syntax, parsed_tree, remaining_source = cls.parse_syntax_and_preceding_comments(
+ proto_source.strip()
+ )
+ return ParsedProtoFileHeaderNode(
+ ProtoFileHeaderNode(list(parsed_tree), syntax, parent=parent),
+ remaining_source.strip(),
+ )
+
+ @classmethod
+ def match_footer(
+ cls,
+ proto_source: str,
+ parent: Optional[ProtoNode] = None,
+ ) -> Optional[str]:
+ trimmed_source = proto_source.strip()
+ if trimmed_source == "":
+ return ""
+ return None
+
+ @classmethod
+ def container_types(cls) -> list[type[ProtoNode]]:
+ return [
ProtoImport,
ProtoMessage,
ProtoPackage,
@@ -66,16 +118,20 @@ def parse_partial_content(partial_proto_content: str) -> ParsedProtoNode:
ProtoSingleLineComment,
ProtoMultiLineComment,
]
- for node_type in node_types:
- try:
- match_result = node_type.match(partial_proto_content)
- except (ValueError, IndexError, TypeError):
- raise ValueError(
- f"Could not parse proto content:\n{partial_proto_content}"
- )
- if match_result is not None:
- return match_result
- raise ValueError(f"Could not parse proto content:\n{partial_proto_content}")
+
+ @classmethod
+ def construct(
+ cls,
+ header_match: "ParsedProtoNode",
+ contained_nodes: list[ProtoNode],
+ footer_match: str,
+ parent: Optional[ProtoNode] = None,
+ ) -> ProtoNode:
+ assert isinstance(header_match, ParsedProtoFileHeaderNode)
+ return cls(
+ header_match.node.syntax,
+ header_match.node.header_nodes + contained_nodes,
+ )
@staticmethod
def parse_syntax_and_preceding_comments(
@@ -108,25 +164,6 @@ def parse_syntax_and_preceding_comments(
return syntax, parsed_tree, proto_content
- @classmethod
- def match(
- cls, proto_content: str, parent: Optional["ProtoNode"] = None
- ) -> Optional[ParsedProtoFileNode]:
- syntax, parsed_tree, proto_content = cls.parse_syntax_and_preceding_comments(
- proto_content
- )
- new_tree: list[ProtoNode] = list(parsed_tree)
- while proto_content:
- # Remove empty statements.
- if proto_content.startswith(";"):
- proto_content = proto_content[1:].strip()
- continue
- match_result = cls.parse_partial_content(proto_content)
- new_tree.append(match_result.node)
- proto_content = match_result.remaining_source.strip()
-
- return ParsedProtoFileNode(cls(syntax, new_tree), proto_content)
-
def normalize(self) -> Optional["ProtoNode"]:
normalized_nodes = [n.normalize() for n in self.nodes]
return ProtoFile(
diff --git a/src/proto_node.py b/src/proto_node.py
index f69c3f4..05f145c 100644
--- a/src/proto_node.py
+++ b/src/proto_node.py
@@ -98,6 +98,7 @@ def match(
proto_source = header_match.remaining_source.strip()
nodes = []
+ footer_match: Optional[str] = None
while proto_source:
# Remove empty statements.
if proto_source.startswith(";"):
@@ -114,9 +115,11 @@ def match(
proto_source = match_result.remaining_source.strip()
if footer_match is None:
- raise ValueError(
- f"Footer was not found when matching container node {cls} for remaining proto source {proto_source}"
- )
+ footer_match = cls.match_footer(proto_source, parent)
+ if footer_match is None:
+ raise ValueError(
+ f"Footer was not found when matching container node {cls} for remaining proto source {proto_source}"
+ )
return ParsedProtoNode(
cls.construct(header_match, nodes, footer_match, parent=parent),
diff --git a/src/util/parser.py b/src/util/parser.py
index dd00352..1bd067f 100644
--- a/src/util/parser.py
+++ b/src/util/parser.py
@@ -13,12 +13,11 @@ def loads(proto_content: str) -> ProtoFile:
try:
parsed_file = ProtoFile.match(proto_content, None)
except ValueError as e:
- raise ParseError(
- f"Proto doesn't have parseable syntax:\n{proto_content}\n{e}"
- )
+ raise ParseError(f"Proto doesn't have parseable syntax:\n{e}")
if parsed_file is None:
raise ParseError(f"Proto doesn't have parseable syntax:\n{proto_content}")
+ assert isinstance(parsed_file.node, ProtoFile)
return parsed_file.node
From f0b88d1586c6ae04aebc385636c7cbe953d29bb2 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Tue, 13 Feb 2024 22:09:45 -0500
Subject: [PATCH 25/35] Add pre-commit badge to README (#82)
---
.pre-commit-config.yaml | 9 +++++----
README.md | 2 ++
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d256485..32d14aa 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -15,14 +15,15 @@ repos:
hooks:
- id: black
- repo: https://github.com/pycqa/isort
- rev: 5.10.1
+ rev: 5.13.2
hooks:
- id: isort
name: isort (python)
- - repo: https://github.com/FelixSeptem/pre-commit-golang.git
- rev: "12f5442f51377b10b26651ad745206bbe1500ad6"
+ - repo: https://github.com/keith/pre-commit-buildifier
+ rev: 6.4.0
hooks:
- - id: bazel-buildifier
+ - id: buildifier
+ - id: buildifier-lint
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.991
hooks:
diff --git a/README.md b/README.md
index 5e98825..1060e46 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# py_proto
+[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/shaldengeki/py_proto/main.svg)](https://results.pre-commit.ci/latest/github/shaldengeki/py_proto/main)
+
This is a Python-based protobuf parser. It is intended to serve as a reference implementation and is _not_ production-ready.
![Build status](https://github.com/shaldengeki/py_proto/actions/workflows/main.yml/badge.svg)
From b548c0d3a3f82ed94471d2045f5b39961f37cbd3 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Tue, 13 Feb 2024 22:16:28 -0500
Subject: [PATCH 26/35] Move badge just a little (#83)
---
.pre-commit-config.yaml | 5 +++++
README.md | 4 +---
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 32d14aa..a22ac4c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,5 +1,10 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
+ci:
+ skip:
+ - buildifier
+ - buildifier-lint
+
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
diff --git a/README.md b/README.md
index 1060e46..7e33b13 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,8 @@
# py_proto
-[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/shaldengeki/py_proto/main.svg)](https://results.pre-commit.ci/latest/github/shaldengeki/py_proto/main)
-
This is a Python-based protobuf parser. It is intended to serve as a reference implementation and is _not_ production-ready.
-![Build status](https://github.com/shaldengeki/py_proto/actions/workflows/main.yml/badge.svg)
+[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/shaldengeki/py_proto/main.svg)](https://results.pre-commit.ci/latest/github/shaldengeki/py_proto/main) ![Build status](https://github.com/shaldengeki/py_proto/actions/workflows/main.yml/badge.svg)
## Usage
From 3ad8d98e3b4743680f0697ec59741014d6c0f4b7 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Tue, 13 Feb 2024 22:18:47 -0500
Subject: [PATCH 27/35] Add dependabot support (#84)
---
.github/dependabot.yml | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 .github/dependabot.yml
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..4c0fa9f
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,10 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ - package-ecosystem: "pip"
+ directory: "/src"
+ schedule:
+ interval: "weekly"
From 86eea726b451292a18906696ae65f2667b3630fa Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 13 Feb 2024 22:19:55 -0500
Subject: [PATCH 28/35] Bump actions/checkout from 2 to 4 (#85)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to
4.
Release notes
Sourced from actions/checkout's
releases.
v4.0.0
What's Changed
New Contributors
Full Changelog: https://github.com/actions/checkout/compare/v3...v4.0.0
v3.6.0
What's Changed
New Contributors
Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0
v3.5.3
What's Changed
New Contributors
Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3
v3.5.2
What's Changed
Full Changelog: https://github.com/actions/checkout/compare/v3.5.1...v3.5.2
v3.5.1
What's Changed
New Contributors
... (truncated)
Changelog
Sourced from actions/checkout's
changelog.
Changelog
v4.1.0
v4.0.0
v3.6.0
v3.5.3
v3.5.2
v3.5.1
v3.5.0
v3.4.0
v3.3.0
v3.2.0
v3.1.0
v3.0.2
... (truncated)
Commits
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=2&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/main.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index e880a90..742c31d 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: bazel test //...
env:
# Bazelisk will download bazel to here
From 3d069d646c4a5a464afc5441560803dfa72059e3 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 13 Feb 2024 22:20:04 -0500
Subject: [PATCH 29/35] Bump black from 22.10.0 to 24.2.0 in /src (#86)
Bumps [black](https://github.com/psf/black) from 22.10.0 to 24.2.0.
Release notes
Sourced from black's
releases.
24.2.0
Stable style
- Fixed a bug where comments where mistakenly removed along with
redundant parentheses
(#4218)
Preview style
- Move the
hug_parens_with_braces_and_square_brackets
feature to the unstable style
due to an outstanding crash and proposed formatting tweaks (#4198)
- Fixed a bug where base expressions caused inconsistent formatting of
** in tenary
expression (#4154)
- Checking for newline before adding one on docstring that is almost
at the line limit
(#4185)
- Remove redundant parentheses in
case
statement
if
guards (#4214).
Configuration
- Fix issue where Black would ignore input files in the
presence of symlinks (#4222)
- Black now ignores
pyproject.toml
that is
missing a tool.black
section when
discovering project root and configuration. Since Black
continues to use version
control as an indicator of project root, this is expected to primarily
change behavior
for users in a monorepo setup (desirably). If you wish to preserve
previous behavior,
simply add an empty [tool.black]
to the previously
discovered pyproject.toml
(#4204)
Output
- Black will swallow any
SyntaxWarning
s or
DeprecationWarning
s produced by the ast
module when performing equivalence checks (#4189)
Integrations
- Add a JSONSchema and provide a validate-pyproject entry-point (#4181)
24.1.1
Bugfix release to fix a bug that made Black unusable on certain file
systems
with strict limits on path length.
Preview style
- Consistently add trailing comma on typed parameters (#4164)
Configuration
- Shorten the length of the name of the cache file to fix crashes on
file systems that
do not support long paths (#4176)
... (truncated)
Changelog
Sourced from black's
changelog.
24.2.0
Stable style
- Fixed a bug where comments where mistakenly removed along with
redundant parentheses
(#4218)
Preview style
- Move the
hug_parens_with_braces_and_square_brackets
feature to the unstable style
due to an outstanding crash and proposed formatting tweaks (#4198)
- Fixed a bug where base expressions caused inconsistent formatting of
** in tenary
expression (#4154)
- Checking for newline before adding one on docstring that is almost
at the line limit
(#4185)
- Remove redundant parentheses in
case
statement
if
guards (#4214).
Configuration
- Fix issue where Black would ignore input files in the
presence of symlinks (#4222)
- Black now ignores
pyproject.toml
that is
missing a tool.black
section when
discovering project root and configuration. Since Black
continues to use version
control as an indicator of project root, this is expected to primarily
change behavior
for users in a monorepo setup (desirably). If you wish to preserve
previous behavior,
simply add an empty [tool.black]
to the previously
discovered pyproject.toml
(#4204)
Output
- Black will swallow any
SyntaxWarning
s or
DeprecationWarning
s produced by the ast
module when performing equivalence checks (#4189)
Integrations
- Add a JSONSchema and provide a validate-pyproject entry-point (#4181)
24.1.1
Bugfix release to fix a bug that made Black unusable on certain file
systems with strict
limits on path length.
Preview style
- Consistently add trailing comma on typed parameters (#4164)
Configuration
- Shorten the length of the name of the cache file to fix crashes on
file systems that
do not support long paths (#4176)
... (truncated)
Commits
6fdf8a4
Prepare release 24.2.0 (#4226)
8af4394
fix: Don't remove comments along with parens (#4218)
35e9776
Bump pre-commit/action from 3.0.0 to 3.0.1 (#4225)
23dfc5b
Fix ignoring input files for symlink reasons (#4222)
a201003
Simplify check for symlinks that resolve outside root (#4221)
dab37a6
Remove redundant parentheses in case
statement
if
guards (#4214)
32230e6
fix: bug where the doublestar operation had inconsistent formatting. (#4154)
7edb50f
fix: additional newline added to docstring when the previous line length
is l...
3e80de3
Bump furo from 2023.9.10 to 2024.1.29 in /docs (#4211)
a08b480
Bump pypa/cibuildwheel from 2.16.4 to 2.16.5 (#4212)
- Additional commits viewable in compare
view
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=black&package-manager=pip&previous-version=22.10.0&new-version=24.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
src/requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/requirements.txt b/src/requirements.txt
index 531c159..c808582 100644
--- a/src/requirements.txt
+++ b/src/requirements.txt
@@ -8,7 +8,7 @@ astroid==2.12.13
# via
# -r src/requirements.txt
# pylint
-black==22.10.0
+black==24.2.0
# via -r src/requirements.txt
cfgv==3.3.1
# via
From 18251a1d7e62c032f1893d7858d6ae2f68f9cb99 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 13 Feb 2024 22:20:16 -0500
Subject: [PATCH 30/35] Bump astroid from 2.12.13 to 3.0.3 in /src (#87)
Bumps [astroid](https://github.com/pylint-dev/astroid) from 2.12.13 to
3.0.3.
Changelog
Sourced from astroid's
changelog.
What's New in astroid 3.0.3?
Release date: 2024-02-04
What's New in astroid 3.0.2?
Release date: 2023-12-12
-
Avoid duplicate inference results for some uses of
typing.X
constructs like
Tuple[Optional[int], ...]
. This was causing pylint to
occasionally omit
messages like deprecated-typing-alias
.
Closes pylint-dev/pylint#9220
What's New in astroid 3.0.1?
Release date: 2023-10-15
What's New in astroid 3.0.0?
Release date: 2023-09-26
-
Add support for Python 3.12, including PEP 695 type parameter
syntax.
Closes #2201
-
Remove support for Python 3.7.
Refs #2137
-
Use the global inference cache when inferring, even without an
explicit
InferenceContext
. This is a significant performance
improvement given how
often methods default to None
for the context argument.
(Linting astroid
itself now takes ~5% less time on Python 3.12; other projects requiring
more
complex inference calculations will see greater speedups.)
... (truncated)
Commits
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=astroid&package-manager=pip&previous-version=2.12.13&new-version=3.0.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
src/requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/requirements.txt b/src/requirements.txt
index c808582..a6ada45 100644
--- a/src/requirements.txt
+++ b/src/requirements.txt
@@ -4,7 +4,7 @@
#
# pip-compile src/requirements.txt
#
-astroid==2.12.13
+astroid==3.0.3
# via
# -r src/requirements.txt
# pylint
From 9776505fbd3df081d032fd5493ac6dd62ecc04bf Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 13 Feb 2024 22:20:53 -0500
Subject: [PATCH 31/35] Bump nodeenv from 1.7.0 to 1.8.0 in /src (#88)
Bumps [nodeenv](https://github.com/ekalinin/nodeenv) from 1.7.0 to
1.8.0.
Release notes
Sourced from nodeenv's
releases.
1.8.0: fix fish; add riscv64; multiple attempt to download node
Changes:
Commits
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=nodeenv&package-manager=pip&previous-version=1.7.0&new-version=1.8.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
src/requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/requirements.txt b/src/requirements.txt
index a6ada45..f0a7241 100644
--- a/src/requirements.txt
+++ b/src/requirements.txt
@@ -50,7 +50,7 @@ mypy-extensions==0.4.3
# via
# -r src/requirements.txt
# black
-nodeenv==1.7.0
+nodeenv==1.8.0
# via
# -r src/requirements.txt
# pre-commit
From 3fee9bb24b7e734cd8a0b69a8557e368e673b03c Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 13 Feb 2024 22:22:11 -0500
Subject: [PATCH 32/35] Bump pathspec from 0.10.2 to 0.12.1 in /src (#89)
Bumps [pathspec](https://github.com/cpburnz/python-pathspec) from 0.10.2
to 0.12.1.
Release notes
Sourced from pathspec's
releases.
v0.12.1
Release v0.12.1. See CHANGES.rst.
v0.12.0
Release v0.12.0. See CHANGES.rst.
v0.11.2
Release v0.11.2. See CHANGES.rst.
v0.11.1
Release v0.11.1. See CHANGES.rst.
v0.11.0
Release v0.11.0. See CHANGES.rst.
v0.10.3
Release v0.10.3. See CHANGES.rst.
Changelog
Sourced from pathspec's
changelog.
0.12.1 (2023-12-10)
Bug fixes:
Issue
[#84](https://github.com/cpburnz/python-pathspec/issues/84)
_:
PathSpec.match_file() returns None since 0.12.0.
.. _Issue
[#84](https://github.com/cpburnz/python-pathspec/issues/84)
: cpburnz/python-pathspec#84
0.12.0 (2023-12-09)
Major changes:
- Dropped support of EOL Python 3.7. See
Pull
[#82](https://github.com/cpburnz/python-pathspec/issues/82)
_.
API changes:
- Signature of protected method
pathspec.pathspec.PathSpec._match_file()
(with a leading
underscore) has been changed from def _match_file(patterns:
Iterable[Pattern], file: str) -> bool
to def
_match_file(patterns: Iterable[Tuple[int, Pattern]], file: str) ->
Tuple[Optional[bool], Optional[int]]
.
New features:
- Added
pathspec.pathspec.PathSpec.check_*()
methods.
These methods behave similarly to .match_*()
but return
additional information in the pathspec.util.CheckResult
objects (e.g., CheckResult.index
indicates the index of the
last pattern that matched the file).
- Added
pathspec.pattern.RegexPattern.pattern
attribute
which stores the original, uncompiled pattern.
Bug fixes:
Issue
[#81](https://github.com/cpburnz/python-pathspec/issues/81)
_:
GitIgnoreSpec behaviors differ from git.
Pull
[#83](https://github.com/cpburnz/python-pathspec/issues/83)
_: Fix
ReadTheDocs builds.
Improvements:
- Mark Python 3.12 as supported. See
Pull
[#82](https://github.com/cpburnz/python-pathspec/issues/82)
_.
- Improve test debugging.
- Improve type hint on on_error parameter on
pathspec.pathspec.PathSpec.match_tree_entries()
.
- Improve type hint on on_error parameter on
pathspec.util.iter_tree_entries()
.
.. _Issue
[#81](https://github.com/cpburnz/python-pathspec/issues/81)
: cpburnz/python-pathspec#81
.. _Pull
[#82](https://github.com/cpburnz/python-pathspec/issues/82)
: cpburnz/python-pathspec#82
.. _Pull
[#83](https://github.com/cpburnz/python-pathspec/issues/83)
: cpburnz/python-pathspec#83
0.11.2 (2023-07-28)
New features:
... (truncated)
Commits
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pathspec&package-manager=pip&previous-version=0.10.2&new-version=0.12.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
src/requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/requirements.txt b/src/requirements.txt
index f0a7241..f1c3836 100644
--- a/src/requirements.txt
+++ b/src/requirements.txt
@@ -54,7 +54,7 @@ nodeenv==1.8.0
# via
# -r src/requirements.txt
# pre-commit
-pathspec==0.10.2
+pathspec==0.12.1
# via
# -r src/requirements.txt
# black
From eb10750d25b26d7af56d7bf2ee842b9dc94d576c Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 13 Feb 2024 22:23:12 -0500
Subject: [PATCH 33/35] Bump distlib from 0.3.6 to 0.3.8 in /src (#90)
Bumps [distlib](https://github.com/pypa/distlib) from 0.3.6 to 0.3.8.
Changelog
Sourced from distlib's
changelog.
0.3.8
Released: 2023-12-12
-
markers
- Fix #209: use
legacy version implementation for Python versions.
-
tests
0.3.7
Released: 2023-07-17
-
database
- Handle newlines when parsing metadata.
-
markers
-
scripts
- Fix shebang computation for source builds of Python. Thanks to Eli
Schwartz for the patch.
-
util
-
Extract tarfiles more safely by incorporating tarfile filters. Thanks
to
Petr Viktorin for the patch.
-
Check for 'has_cert' attribute before using it. Thanks to Lumir
Balhar for
the patch.
-
Fix #203:
Handle parsing of export entries to allow script names such as
"," or ",foo". Thanks to Flavio Amurrio for the
report.
-
versions
... (truncated)
Commits
ab5f8e7
Changes for 0.3.8.
86bb212
Update change log.
488599f
Updates based on flake8 checks.
0e261af
Use legacy version implementation for Python itself.
8242f39
Update copyright years.
e27569b
Fix #208:
Handle deprecation removals in Python 3.13.
65a014b
Update requirements and CI matrix.
124108a
Skip test for non-final Python versions.
ff48e09
Fix #206:
include tox.ini in sdist.
eeaa18d
Fix #204: Use
symlinks in venv creation during test.
- Additional commits viewable in compare
view
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=distlib&package-manager=pip&previous-version=0.3.6&new-version=0.3.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
src/requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/requirements.txt b/src/requirements.txt
index f1c3836..ac0152e 100644
--- a/src/requirements.txt
+++ b/src/requirements.txt
@@ -22,7 +22,7 @@ dill==0.3.6
# via
# -r src/requirements.txt
# pylint
-distlib==0.3.6
+distlib==0.3.8
# via
# -r src/requirements.txt
# virtualenv
From 168931bc207647b887112741a4910ffa47d8b3b4 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Tue, 13 Feb 2024 22:26:28 -0500
Subject: [PATCH 34/35] Update to bazel 7 (#91)
---
.bazelversion | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.bazelversion b/.bazelversion
index 09b254e..a8907c0 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-6.0.0
+7.0.2
From f8ed13f53f169db0cf4179fc6ea37a9bae0d5ee8 Mon Sep 17 00:00:00 2001
From: Charles OuGuo
Date: Tue, 13 Feb 2024 22:37:47 -0500
Subject: [PATCH 35/35] Use bzlmod (#92)
---
MODULE.bazel | 15 +
MODULE.bazel.lock | 2312 +++++++++++++++++++++++++++++++++++++++++++++
WORKSPACE | 36 -
3 files changed, 2327 insertions(+), 36 deletions(-)
create mode 100644 MODULE.bazel
create mode 100644 MODULE.bazel.lock
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 0000000..83fd0ca
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,15 @@
+bazel_dep(name = "rules_python", version = "0.31.0")
+
+python = use_extension("@rules_python//python/extensions:python.bzl", "python")
+python.toolchain(
+ python_version = "3.10",
+)
+
+pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
+pip.parse(
+ python_version = "3.10",
+ requirements_lock = "//src:requirements.txt",
+)
+use_repo(pip, "py_proto_deps")
+
+bazel_dep(name = "bazel_skylib", version = "1.5.0")
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
new file mode 100644
index 0000000..aeeacbe
--- /dev/null
+++ b/MODULE.bazel.lock
@@ -0,0 +1,2312 @@
+{
+ "lockFileVersion": 3,
+ "moduleFileHash": "60ddefc0e85720d83b75b5ac5f314791a9cd92eee654d7ca947f3c9e3d587d0b",
+ "flags": {
+ "cmdRegistries": [
+ "https://bcr.bazel.build/"
+ ],
+ "cmdModuleOverrides": {},
+ "allowedYankedVersions": [],
+ "envVarAllowedYankedVersions": "",
+ "ignoreDevDependency": false,
+ "directDependenciesMode": "WARNING",
+ "compatibilityMode": "ERROR"
+ },
+ "localOverrideHashes": {
+ "bazel_tools": "922ea6752dc9105de5af957f7a99a6933c0a6a712d23df6aad16a9c399f7e787"
+ },
+ "moduleDepGraph": {
+ "": {
+ "name": "",
+ "version": "",
+ "key": "",
+ "repoName": "",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [
+ {
+ "extensionBzlFile": "@rules_python//python/extensions:python.bzl",
+ "extensionName": "python",
+ "usingModule": "",
+ "location": {
+ "file": "@@//:MODULE.bazel",
+ "line": 2,
+ "column": 23
+ },
+ "imports": {},
+ "devImports": [],
+ "tags": [
+ {
+ "tagName": "toolchain",
+ "attributeValues": {
+ "python_version": "3.10"
+ },
+ "devDependency": false,
+ "location": {
+ "file": "@@//:MODULE.bazel",
+ "line": 3,
+ "column": 17
+ }
+ }
+ ],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ },
+ {
+ "extensionBzlFile": "@rules_python//python/extensions:pip.bzl",
+ "extensionName": "pip",
+ "usingModule": "",
+ "location": {
+ "file": "@@//:MODULE.bazel",
+ "line": 7,
+ "column": 20
+ },
+ "imports": {
+ "py_proto_deps": "py_proto_deps"
+ },
+ "devImports": [],
+ "tags": [
+ {
+ "tagName": "parse",
+ "attributeValues": {
+ "python_version": "3.10",
+ "requirements_lock": "//src:requirements.txt"
+ },
+ "devDependency": false,
+ "location": {
+ "file": "@@//:MODULE.bazel",
+ "line": 8,
+ "column": 10
+ }
+ }
+ ],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ }
+ ],
+ "deps": {
+ "rules_python": "rules_python@0.31.0",
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ }
+ },
+ "rules_python@0.31.0": {
+ "name": "rules_python",
+ "version": "0.31.0",
+ "key": "rules_python@0.31.0",
+ "repoName": "rules_python",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [
+ "@pythons_hub//:all"
+ ],
+ "extensionUsages": [
+ {
+ "extensionBzlFile": "@rules_python//python/private/bzlmod:internal_deps.bzl",
+ "extensionName": "internal_deps",
+ "usingModule": "rules_python@0.31.0",
+ "location": {
+ "file": "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel",
+ "line": 15,
+ "column": 30
+ },
+ "imports": {
+ "rules_python_internal": "rules_python_internal",
+ "pypi__build": "pypi__build",
+ "pypi__click": "pypi__click",
+ "pypi__colorama": "pypi__colorama",
+ "pypi__importlib_metadata": "pypi__importlib_metadata",
+ "pypi__installer": "pypi__installer",
+ "pypi__more_itertools": "pypi__more_itertools",
+ "pypi__packaging": "pypi__packaging",
+ "pypi__pep517": "pypi__pep517",
+ "pypi__pip": "pypi__pip",
+ "pypi__pip_tools": "pypi__pip_tools",
+ "pypi__pyproject_hooks": "pypi__pyproject_hooks",
+ "pypi__setuptools": "pypi__setuptools",
+ "pypi__tomli": "pypi__tomli",
+ "pypi__wheel": "pypi__wheel",
+ "pypi__zipp": "pypi__zipp"
+ },
+ "devImports": [],
+ "tags": [
+ {
+ "tagName": "install",
+ "attributeValues": {},
+ "devDependency": false,
+ "location": {
+ "file": "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel",
+ "line": 16,
+ "column": 22
+ }
+ }
+ ],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ },
+ {
+ "extensionBzlFile": "@rules_python//python/extensions:python.bzl",
+ "extensionName": "python",
+ "usingModule": "rules_python@0.31.0",
+ "location": {
+ "file": "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel",
+ "line": 41,
+ "column": 23
+ },
+ "imports": {
+ "pythons_hub": "pythons_hub"
+ },
+ "devImports": [],
+ "tags": [
+ {
+ "tagName": "toolchain",
+ "attributeValues": {
+ "is_default": true,
+ "python_version": "3.11"
+ },
+ "devDependency": false,
+ "location": {
+ "file": "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel",
+ "line": 47,
+ "column": 17
+ }
+ }
+ ],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ }
+ ],
+ "deps": {
+ "bazel_features": "bazel_features@1.1.1",
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "platforms": "platforms@0.0.7",
+ "rules_proto": "rules_proto@5.3.0-21.7",
+ "com_google_protobuf": "protobuf@21.7",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0",
+ "urls": [
+ "https://github.com/bazelbuild/rules_python/releases/download/0.31.0/rules_python-0.31.0.tar.gz"
+ ],
+ "integrity": "sha256-xovcT77CXeW1STuIGc/Id8TqKZwNyxXCRMWgAgjN4xE=",
+ "strip_prefix": "rules_python-0.31.0",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/rules_python/0.31.0/patches/module_dot_bazel_version.patch": "sha256-j2KF6j66J2fRAGtc56Zj7Hp1dTGqOWPAR3+IODr0oLQ="
+ },
+ "remote_patch_strip": 1
+ }
+ }
+ },
+ "bazel_skylib@1.5.0": {
+ "name": "bazel_skylib",
+ "version": "1.5.0",
+ "key": "bazel_skylib@1.5.0",
+ "repoName": "bazel_skylib",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [
+ "//toolchains/unittest:cmd_toolchain",
+ "//toolchains/unittest:bash_toolchain"
+ ],
+ "extensionUsages": [],
+ "deps": {
+ "platforms": "platforms@0.0.7",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "bazel_skylib~1.5.0",
+ "urls": [
+ "https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz"
+ ],
+ "integrity": "sha256-zVWgYudjuTSZIfD124w5MyiNyLpPdt2UFqrGis7jy5Q=",
+ "strip_prefix": "",
+ "remote_patches": {},
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "bazel_tools@_": {
+ "name": "bazel_tools",
+ "version": "",
+ "key": "bazel_tools@_",
+ "repoName": "bazel_tools",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [
+ "@local_config_cc_toolchains//:all",
+ "@local_config_sh//:local_sh_toolchain"
+ ],
+ "extensionUsages": [
+ {
+ "extensionBzlFile": "@bazel_tools//tools/cpp:cc_configure.bzl",
+ "extensionName": "cc_configure_extension",
+ "usingModule": "bazel_tools@_",
+ "location": {
+ "file": "@@bazel_tools//:MODULE.bazel",
+ "line": 17,
+ "column": 29
+ },
+ "imports": {
+ "local_config_cc": "local_config_cc",
+ "local_config_cc_toolchains": "local_config_cc_toolchains"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ },
+ {
+ "extensionBzlFile": "@bazel_tools//tools/osx:xcode_configure.bzl",
+ "extensionName": "xcode_configure_extension",
+ "usingModule": "bazel_tools@_",
+ "location": {
+ "file": "@@bazel_tools//:MODULE.bazel",
+ "line": 21,
+ "column": 32
+ },
+ "imports": {
+ "local_config_xcode": "local_config_xcode"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ },
+ {
+ "extensionBzlFile": "@rules_java//java:extensions.bzl",
+ "extensionName": "toolchains",
+ "usingModule": "bazel_tools@_",
+ "location": {
+ "file": "@@bazel_tools//:MODULE.bazel",
+ "line": 24,
+ "column": 32
+ },
+ "imports": {
+ "local_jdk": "local_jdk",
+ "remote_java_tools": "remote_java_tools",
+ "remote_java_tools_linux": "remote_java_tools_linux",
+ "remote_java_tools_windows": "remote_java_tools_windows",
+ "remote_java_tools_darwin_x86_64": "remote_java_tools_darwin_x86_64",
+ "remote_java_tools_darwin_arm64": "remote_java_tools_darwin_arm64"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ },
+ {
+ "extensionBzlFile": "@bazel_tools//tools/sh:sh_configure.bzl",
+ "extensionName": "sh_configure_extension",
+ "usingModule": "bazel_tools@_",
+ "location": {
+ "file": "@@bazel_tools//:MODULE.bazel",
+ "line": 35,
+ "column": 39
+ },
+ "imports": {
+ "local_config_sh": "local_config_sh"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ },
+ {
+ "extensionBzlFile": "@bazel_tools//tools/test:extensions.bzl",
+ "extensionName": "remote_coverage_tools_extension",
+ "usingModule": "bazel_tools@_",
+ "location": {
+ "file": "@@bazel_tools//:MODULE.bazel",
+ "line": 39,
+ "column": 48
+ },
+ "imports": {
+ "remote_coverage_tools": "remote_coverage_tools"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ },
+ {
+ "extensionBzlFile": "@bazel_tools//tools/android:android_extensions.bzl",
+ "extensionName": "remote_android_tools_extensions",
+ "usingModule": "bazel_tools@_",
+ "location": {
+ "file": "@@bazel_tools//:MODULE.bazel",
+ "line": 42,
+ "column": 42
+ },
+ "imports": {
+ "android_gmaven_r8": "android_gmaven_r8",
+ "android_tools": "android_tools"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ }
+ ],
+ "deps": {
+ "rules_cc": "rules_cc@0.0.9",
+ "rules_java": "rules_java@7.1.0",
+ "rules_license": "rules_license@0.0.7",
+ "rules_proto": "rules_proto@5.3.0-21.7",
+ "rules_python": "rules_python@0.31.0",
+ "platforms": "platforms@0.0.7",
+ "com_google_protobuf": "protobuf@21.7",
+ "zlib": "zlib@1.3",
+ "build_bazel_apple_support": "apple_support@1.5.0",
+ "local_config_platform": "local_config_platform@_"
+ }
+ },
+ "local_config_platform@_": {
+ "name": "local_config_platform",
+ "version": "",
+ "key": "local_config_platform@_",
+ "repoName": "local_config_platform",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "platforms": "platforms@0.0.7",
+ "bazel_tools": "bazel_tools@_"
+ }
+ },
+ "bazel_features@1.1.1": {
+ "name": "bazel_features",
+ "version": "1.1.1",
+ "key": "bazel_features@1.1.1",
+ "repoName": "bazel_features",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [
+ {
+ "extensionBzlFile": "@bazel_features//private:extensions.bzl",
+ "extensionName": "version_extension",
+ "usingModule": "bazel_features@1.1.1",
+ "location": {
+ "file": "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel",
+ "line": 6,
+ "column": 24
+ },
+ "imports": {
+ "bazel_features_globals": "bazel_features_globals",
+ "bazel_features_version": "bazel_features_version"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ }
+ ],
+ "deps": {
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "bazel_features~1.1.1",
+ "urls": [
+ "https://github.com/bazel-contrib/bazel_features/releases/download/v1.1.1/bazel_features-v1.1.1.tar.gz"
+ ],
+ "integrity": "sha256-YsJuQn5cvHUQJERpJ2IuOYqdzfMsZDJSOIFXCdEcEag=",
+ "strip_prefix": "bazel_features-1.1.1",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/bazel_features/1.1.1/patches/module_dot_bazel_version.patch": "sha256-+56MAEsc7bYN/Pzhn252ZQUxiRzZg9bynXj1qpsmCYs="
+ },
+ "remote_patch_strip": 1
+ }
+ }
+ },
+ "platforms@0.0.7": {
+ "name": "platforms",
+ "version": "0.0.7",
+ "key": "platforms@0.0.7",
+ "repoName": "platforms",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "rules_license": "rules_license@0.0.7",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "platforms",
+ "urls": [
+ "https://github.com/bazelbuild/platforms/releases/download/0.0.7/platforms-0.0.7.tar.gz"
+ ],
+ "integrity": "sha256-OlYcmee9vpFzqmU/1Xn+hJ8djWc5V4CrR3Cx84FDHVE=",
+ "strip_prefix": "",
+ "remote_patches": {},
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "rules_proto@5.3.0-21.7": {
+ "name": "rules_proto",
+ "version": "5.3.0-21.7",
+ "key": "rules_proto@5.3.0-21.7",
+ "repoName": "rules_proto",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "com_google_protobuf": "protobuf@21.7",
+ "rules_cc": "rules_cc@0.0.9",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_proto~5.3.0-21.7",
+ "urls": [
+ "https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz"
+ ],
+ "integrity": "sha256-3D+yBqLLNEG0heseQjFlsjEjWh6psDG0Qzz3vB+kYN0=",
+ "strip_prefix": "rules_proto-5.3.0-21.7",
+ "remote_patches": {},
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "protobuf@21.7": {
+ "name": "protobuf",
+ "version": "21.7",
+ "key": "protobuf@21.7",
+ "repoName": "protobuf",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [
+ {
+ "extensionBzlFile": "@rules_jvm_external//:extensions.bzl",
+ "extensionName": "maven",
+ "usingModule": "protobuf@21.7",
+ "location": {
+ "file": "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel",
+ "line": 22,
+ "column": 22
+ },
+ "imports": {
+ "maven": "maven"
+ },
+ "devImports": [],
+ "tags": [
+ {
+ "tagName": "install",
+ "attributeValues": {
+ "name": "maven",
+ "artifacts": [
+ "com.google.code.findbugs:jsr305:3.0.2",
+ "com.google.code.gson:gson:2.8.9",
+ "com.google.errorprone:error_prone_annotations:2.3.2",
+ "com.google.j2objc:j2objc-annotations:1.3",
+ "com.google.guava:guava:31.1-jre",
+ "com.google.guava:guava-testlib:31.1-jre",
+ "com.google.truth:truth:1.1.2",
+ "junit:junit:4.13.2",
+ "org.mockito:mockito-core:4.3.1"
+ ]
+ },
+ "devDependency": false,
+ "location": {
+ "file": "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel",
+ "line": 24,
+ "column": 14
+ }
+ }
+ ],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ }
+ ],
+ "deps": {
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "rules_python": "rules_python@0.31.0",
+ "rules_cc": "rules_cc@0.0.9",
+ "rules_proto": "rules_proto@5.3.0-21.7",
+ "rules_java": "rules_java@7.1.0",
+ "rules_pkg": "rules_pkg@0.7.0",
+ "com_google_abseil": "abseil-cpp@20211102.0",
+ "zlib": "zlib@1.3",
+ "upb": "upb@0.0.0-20220923-a547704",
+ "rules_jvm_external": "rules_jvm_external@4.4.2",
+ "com_google_googletest": "googletest@1.11.0",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "protobuf~21.7",
+ "urls": [
+ "https://github.com/protocolbuffers/protobuf/releases/download/v21.7/protobuf-all-21.7.zip"
+ ],
+ "integrity": "sha256-VJOiH17T/FAuZv7GuUScBqVRztYwAvpIkDxA36jeeko=",
+ "strip_prefix": "protobuf-21.7",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/protobuf/21.7/patches/add_module_dot_bazel.patch": "sha256-q3V2+eq0v2XF0z8z+V+QF4cynD6JvHI1y3kI/+rzl5s=",
+ "https://bcr.bazel.build/modules/protobuf/21.7/patches/add_module_dot_bazel_for_examples.patch": "sha256-O7YP6s3lo/1opUiO0jqXYORNHdZ/2q3hjz1QGy8QdIU=",
+ "https://bcr.bazel.build/modules/protobuf/21.7/patches/relative_repo_names.patch": "sha256-RK9RjW8T5UJNG7flIrnFiNE9vKwWB+8uWWtJqXYT0w4=",
+ "https://bcr.bazel.build/modules/protobuf/21.7/patches/add_missing_files.patch": "sha256-Hyne4DG2u5bXcWHNxNMirA2QFAe/2Cl8oMm1XJdkQIY="
+ },
+ "remote_patch_strip": 1
+ }
+ }
+ },
+ "rules_cc@0.0.9": {
+ "name": "rules_cc",
+ "version": "0.0.9",
+ "key": "rules_cc@0.0.9",
+ "repoName": "rules_cc",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [
+ "@local_config_cc_toolchains//:all"
+ ],
+ "extensionUsages": [
+ {
+ "extensionBzlFile": "@bazel_tools//tools/cpp:cc_configure.bzl",
+ "extensionName": "cc_configure_extension",
+ "usingModule": "rules_cc@0.0.9",
+ "location": {
+ "file": "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel",
+ "line": 9,
+ "column": 29
+ },
+ "imports": {
+ "local_config_cc_toolchains": "local_config_cc_toolchains"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ }
+ ],
+ "deps": {
+ "platforms": "platforms@0.0.7",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_cc~0.0.9",
+ "urls": [
+ "https://github.com/bazelbuild/rules_cc/releases/download/0.0.9/rules_cc-0.0.9.tar.gz"
+ ],
+ "integrity": "sha256-IDeHW5pEVtzkp50RKorohbvEqtlo5lh9ym5k86CQDN8=",
+ "strip_prefix": "rules_cc-0.0.9",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/rules_cc/0.0.9/patches/module_dot_bazel_version.patch": "sha256-mM+qzOI0SgAdaJBlWOSMwMPKpaA9b7R37Hj/tp5bb4g="
+ },
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "rules_java@7.1.0": {
+ "name": "rules_java",
+ "version": "7.1.0",
+ "key": "rules_java@7.1.0",
+ "repoName": "rules_java",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [
+ "//toolchains:all",
+ "@local_jdk//:runtime_toolchain_definition",
+ "@local_jdk//:bootstrap_runtime_toolchain_definition",
+ "@remotejdk11_linux_toolchain_config_repo//:all",
+ "@remotejdk11_linux_aarch64_toolchain_config_repo//:all",
+ "@remotejdk11_linux_ppc64le_toolchain_config_repo//:all",
+ "@remotejdk11_linux_s390x_toolchain_config_repo//:all",
+ "@remotejdk11_macos_toolchain_config_repo//:all",
+ "@remotejdk11_macos_aarch64_toolchain_config_repo//:all",
+ "@remotejdk11_win_toolchain_config_repo//:all",
+ "@remotejdk11_win_arm64_toolchain_config_repo//:all",
+ "@remotejdk17_linux_toolchain_config_repo//:all",
+ "@remotejdk17_linux_aarch64_toolchain_config_repo//:all",
+ "@remotejdk17_linux_ppc64le_toolchain_config_repo//:all",
+ "@remotejdk17_linux_s390x_toolchain_config_repo//:all",
+ "@remotejdk17_macos_toolchain_config_repo//:all",
+ "@remotejdk17_macos_aarch64_toolchain_config_repo//:all",
+ "@remotejdk17_win_toolchain_config_repo//:all",
+ "@remotejdk17_win_arm64_toolchain_config_repo//:all",
+ "@remotejdk21_linux_toolchain_config_repo//:all",
+ "@remotejdk21_linux_aarch64_toolchain_config_repo//:all",
+ "@remotejdk21_macos_toolchain_config_repo//:all",
+ "@remotejdk21_macos_aarch64_toolchain_config_repo//:all",
+ "@remotejdk21_win_toolchain_config_repo//:all"
+ ],
+ "extensionUsages": [
+ {
+ "extensionBzlFile": "@rules_java//java:extensions.bzl",
+ "extensionName": "toolchains",
+ "usingModule": "rules_java@7.1.0",
+ "location": {
+ "file": "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel",
+ "line": 19,
+ "column": 27
+ },
+ "imports": {
+ "remote_java_tools": "remote_java_tools",
+ "remote_java_tools_linux": "remote_java_tools_linux",
+ "remote_java_tools_windows": "remote_java_tools_windows",
+ "remote_java_tools_darwin_x86_64": "remote_java_tools_darwin_x86_64",
+ "remote_java_tools_darwin_arm64": "remote_java_tools_darwin_arm64",
+ "local_jdk": "local_jdk",
+ "remotejdk11_linux_toolchain_config_repo": "remotejdk11_linux_toolchain_config_repo",
+ "remotejdk11_linux_aarch64_toolchain_config_repo": "remotejdk11_linux_aarch64_toolchain_config_repo",
+ "remotejdk11_linux_ppc64le_toolchain_config_repo": "remotejdk11_linux_ppc64le_toolchain_config_repo",
+ "remotejdk11_linux_s390x_toolchain_config_repo": "remotejdk11_linux_s390x_toolchain_config_repo",
+ "remotejdk11_macos_toolchain_config_repo": "remotejdk11_macos_toolchain_config_repo",
+ "remotejdk11_macos_aarch64_toolchain_config_repo": "remotejdk11_macos_aarch64_toolchain_config_repo",
+ "remotejdk11_win_toolchain_config_repo": "remotejdk11_win_toolchain_config_repo",
+ "remotejdk11_win_arm64_toolchain_config_repo": "remotejdk11_win_arm64_toolchain_config_repo",
+ "remotejdk17_linux_toolchain_config_repo": "remotejdk17_linux_toolchain_config_repo",
+ "remotejdk17_linux_aarch64_toolchain_config_repo": "remotejdk17_linux_aarch64_toolchain_config_repo",
+ "remotejdk17_linux_ppc64le_toolchain_config_repo": "remotejdk17_linux_ppc64le_toolchain_config_repo",
+ "remotejdk17_linux_s390x_toolchain_config_repo": "remotejdk17_linux_s390x_toolchain_config_repo",
+ "remotejdk17_macos_toolchain_config_repo": "remotejdk17_macos_toolchain_config_repo",
+ "remotejdk17_macos_aarch64_toolchain_config_repo": "remotejdk17_macos_aarch64_toolchain_config_repo",
+ "remotejdk17_win_toolchain_config_repo": "remotejdk17_win_toolchain_config_repo",
+ "remotejdk17_win_arm64_toolchain_config_repo": "remotejdk17_win_arm64_toolchain_config_repo",
+ "remotejdk21_linux_toolchain_config_repo": "remotejdk21_linux_toolchain_config_repo",
+ "remotejdk21_linux_aarch64_toolchain_config_repo": "remotejdk21_linux_aarch64_toolchain_config_repo",
+ "remotejdk21_macos_toolchain_config_repo": "remotejdk21_macos_toolchain_config_repo",
+ "remotejdk21_macos_aarch64_toolchain_config_repo": "remotejdk21_macos_aarch64_toolchain_config_repo",
+ "remotejdk21_win_toolchain_config_repo": "remotejdk21_win_toolchain_config_repo"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ }
+ ],
+ "deps": {
+ "platforms": "platforms@0.0.7",
+ "rules_cc": "rules_cc@0.0.9",
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "rules_proto": "rules_proto@5.3.0-21.7",
+ "rules_license": "rules_license@0.0.7",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0",
+ "urls": [
+ "https://github.com/bazelbuild/rules_java/releases/download/7.1.0/rules_java-7.1.0.tar.gz"
+ ],
+ "integrity": "sha256-o3pOX2OrgnFuXdau75iO2EYcegC46TYnImKJn1h81OE=",
+ "strip_prefix": "",
+ "remote_patches": {},
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "rules_license@0.0.7": {
+ "name": "rules_license",
+ "version": "0.0.7",
+ "key": "rules_license@0.0.7",
+ "repoName": "rules_license",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_license~0.0.7",
+ "urls": [
+ "https://github.com/bazelbuild/rules_license/releases/download/0.0.7/rules_license-0.0.7.tar.gz"
+ ],
+ "integrity": "sha256-RTHezLkTY5ww5cdRKgVNXYdWmNrrddjPkPKEN1/nw2A=",
+ "strip_prefix": "",
+ "remote_patches": {},
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "zlib@1.3": {
+ "name": "zlib",
+ "version": "1.3",
+ "key": "zlib@1.3",
+ "repoName": "zlib",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "platforms": "platforms@0.0.7",
+ "rules_cc": "rules_cc@0.0.9",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "zlib~1.3",
+ "urls": [
+ "https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz"
+ ],
+ "integrity": "sha256-/wukwpIBPbwnUws6geH5qBPNOd4Byl4Pi/NVcC76WT4=",
+ "strip_prefix": "zlib-1.3",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/zlib/1.3/patches/add_build_file.patch": "sha256-Ei+FYaaOo7A3jTKunMEodTI0Uw5NXQyZEcboMC8JskY=",
+ "https://bcr.bazel.build/modules/zlib/1.3/patches/module_dot_bazel.patch": "sha256-fPWLM+2xaF/kuy+kZc1YTfW6hNjrkG400Ho7gckuyJk="
+ },
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "apple_support@1.5.0": {
+ "name": "apple_support",
+ "version": "1.5.0",
+ "key": "apple_support@1.5.0",
+ "repoName": "build_bazel_apple_support",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [
+ "@local_config_apple_cc_toolchains//:all"
+ ],
+ "extensionUsages": [
+ {
+ "extensionBzlFile": "@build_bazel_apple_support//crosstool:setup.bzl",
+ "extensionName": "apple_cc_configure_extension",
+ "usingModule": "apple_support@1.5.0",
+ "location": {
+ "file": "https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel",
+ "line": 17,
+ "column": 35
+ },
+ "imports": {
+ "local_config_apple_cc": "local_config_apple_cc",
+ "local_config_apple_cc_toolchains": "local_config_apple_cc_toolchains"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ }
+ ],
+ "deps": {
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "platforms": "platforms@0.0.7",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "apple_support~1.5.0",
+ "urls": [
+ "https://github.com/bazelbuild/apple_support/releases/download/1.5.0/apple_support.1.5.0.tar.gz"
+ ],
+ "integrity": "sha256-miM41vja0yRPgj8txghKA+TQ+7J8qJLclw5okNW0gYQ=",
+ "strip_prefix": "",
+ "remote_patches": {},
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "rules_pkg@0.7.0": {
+ "name": "rules_pkg",
+ "version": "0.7.0",
+ "key": "rules_pkg@0.7.0",
+ "repoName": "rules_pkg",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "rules_python": "rules_python@0.31.0",
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "rules_license": "rules_license@0.0.7",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_pkg~0.7.0",
+ "urls": [
+ "https://github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz"
+ ],
+ "integrity": "sha256-iimOgydi7aGDBZfWT+fbWBeKqEzVkm121bdE1lWJQcI=",
+ "strip_prefix": "",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/rules_pkg/0.7.0/patches/module_dot_bazel.patch": "sha256-4OaEPZwYF6iC71ZTDg6MJ7LLqX7ZA0/kK4mT+4xKqiE="
+ },
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "abseil-cpp@20211102.0": {
+ "name": "abseil-cpp",
+ "version": "20211102.0",
+ "key": "abseil-cpp@20211102.0",
+ "repoName": "abseil-cpp",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "rules_cc": "rules_cc@0.0.9",
+ "platforms": "platforms@0.0.7",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "abseil-cpp~20211102.0",
+ "urls": [
+ "https://github.com/abseil/abseil-cpp/archive/refs/tags/20211102.0.tar.gz"
+ ],
+ "integrity": "sha256-3PcbnLqNwMqZQMSzFqDHlr6Pq0KwcLtrfKtitI8OZsQ=",
+ "strip_prefix": "abseil-cpp-20211102.0",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/patches/module_dot_bazel.patch": "sha256-4izqopgGCey4jVZzl/w3M2GVPNohjh2B5TmbThZNvPY="
+ },
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "upb@0.0.0-20220923-a547704": {
+ "name": "upb",
+ "version": "0.0.0-20220923-a547704",
+ "key": "upb@0.0.0-20220923-a547704",
+ "repoName": "upb",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "rules_proto": "rules_proto@5.3.0-21.7",
+ "com_google_protobuf": "protobuf@21.7",
+ "com_google_absl": "abseil-cpp@20211102.0",
+ "platforms": "platforms@0.0.7",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "upb~0.0.0-20220923-a547704",
+ "urls": [
+ "https://github.com/protocolbuffers/upb/archive/a5477045acaa34586420942098f5fecd3570f577.tar.gz"
+ ],
+ "integrity": "sha256-z39x6v+QskwaKLSWRan/A6mmwecTQpHOcJActj5zZLU=",
+ "strip_prefix": "upb-a5477045acaa34586420942098f5fecd3570f577",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/patches/module_dot_bazel.patch": "sha256-wH4mNS6ZYy+8uC0HoAft/c7SDsq2Kxf+J8dUakXhaB0="
+ },
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "rules_jvm_external@4.4.2": {
+ "name": "rules_jvm_external",
+ "version": "4.4.2",
+ "key": "rules_jvm_external@4.4.2",
+ "repoName": "rules_jvm_external",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [
+ {
+ "extensionBzlFile": "@rules_jvm_external//:non-module-deps.bzl",
+ "extensionName": "non_module_deps",
+ "usingModule": "rules_jvm_external@4.4.2",
+ "location": {
+ "file": "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel",
+ "line": 9,
+ "column": 32
+ },
+ "imports": {
+ "io_bazel_rules_kotlin": "io_bazel_rules_kotlin"
+ },
+ "devImports": [],
+ "tags": [],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ },
+ {
+ "extensionBzlFile": ":extensions.bzl",
+ "extensionName": "maven",
+ "usingModule": "rules_jvm_external@4.4.2",
+ "location": {
+ "file": "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel",
+ "line": 16,
+ "column": 22
+ },
+ "imports": {
+ "rules_jvm_external_deps": "rules_jvm_external_deps"
+ },
+ "devImports": [],
+ "tags": [
+ {
+ "tagName": "install",
+ "attributeValues": {
+ "name": "rules_jvm_external_deps",
+ "artifacts": [
+ "com.google.cloud:google-cloud-core:1.93.10",
+ "com.google.cloud:google-cloud-storage:1.113.4",
+ "com.google.code.gson:gson:2.9.0",
+ "org.apache.maven:maven-artifact:3.8.6",
+ "software.amazon.awssdk:s3:2.17.183"
+ ],
+ "lock_file": "@rules_jvm_external//:rules_jvm_external_deps_install.json"
+ },
+ "devDependency": false,
+ "location": {
+ "file": "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel",
+ "line": 18,
+ "column": 14
+ }
+ }
+ ],
+ "hasDevUseExtension": false,
+ "hasNonDevUseExtension": true
+ }
+ ],
+ "deps": {
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "io_bazel_stardoc": "stardoc@0.5.1",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_jvm_external~4.4.2",
+ "urls": [
+ "https://github.com/bazelbuild/rules_jvm_external/archive/refs/tags/4.4.2.zip"
+ ],
+ "integrity": "sha256-c1YC9QgT6y6pPKP15DsZWb2AshO4NqB6YqKddXZwt3s=",
+ "strip_prefix": "rules_jvm_external-4.4.2",
+ "remote_patches": {},
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "googletest@1.11.0": {
+ "name": "googletest",
+ "version": "1.11.0",
+ "key": "googletest@1.11.0",
+ "repoName": "googletest",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "com_google_absl": "abseil-cpp@20211102.0",
+ "platforms": "platforms@0.0.7",
+ "rules_cc": "rules_cc@0.0.9",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "googletest~1.11.0",
+ "urls": [
+ "https://github.com/google/googletest/archive/refs/tags/release-1.11.0.tar.gz"
+ ],
+ "integrity": "sha256-tIcL8SH/d5W6INILzdhie44Ijy0dqymaAxwQNO3ck9U=",
+ "strip_prefix": "googletest-release-1.11.0",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/googletest/1.11.0/patches/module_dot_bazel.patch": "sha256-HuahEdI/n8KCI071sN3CEziX+7qP/Ec77IWayYunLP0="
+ },
+ "remote_patch_strip": 0
+ }
+ }
+ },
+ "stardoc@0.5.1": {
+ "name": "stardoc",
+ "version": "0.5.1",
+ "key": "stardoc@0.5.1",
+ "repoName": "stardoc",
+ "executionPlatformsToRegister": [],
+ "toolchainsToRegister": [],
+ "extensionUsages": [],
+ "deps": {
+ "bazel_skylib": "bazel_skylib@1.5.0",
+ "rules_java": "rules_java@7.1.0",
+ "bazel_tools": "bazel_tools@_",
+ "local_config_platform": "local_config_platform@_"
+ },
+ "repoSpec": {
+ "bzlFile": "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "stardoc~0.5.1",
+ "urls": [
+ "https://github.com/bazelbuild/stardoc/releases/download/0.5.1/stardoc-0.5.1.tar.gz"
+ ],
+ "integrity": "sha256-qoFNrgrEALurLoiB+ZFcb0fElmS/CHxAmhX5BDjSwj4=",
+ "strip_prefix": "",
+ "remote_patches": {
+ "https://bcr.bazel.build/modules/stardoc/0.5.1/patches/module_dot_bazel.patch": "sha256-UAULCuTpJE7SG0YrR9XLjMfxMRmbP+za3uW9ONZ5rjI="
+ },
+ "remote_patch_strip": 0
+ }
+ }
+ }
+ },
+ "moduleExtensions": {
+ "@@apple_support~1.5.0//crosstool:setup.bzl%apple_cc_configure_extension": {
+ "general": {
+ "bzlTransitiveDigest": "pMLFCYaRPkgXPQ8vtuNkMfiHfPmRBy6QJfnid4sWfv0=",
+ "accumulatedFileDigests": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "local_config_apple_cc": {
+ "bzlFile": "@@apple_support~1.5.0//crosstool:setup.bzl",
+ "ruleClassName": "_apple_cc_autoconf",
+ "attributes": {
+ "name": "apple_support~1.5.0~apple_cc_configure_extension~local_config_apple_cc"
+ }
+ },
+ "local_config_apple_cc_toolchains": {
+ "bzlFile": "@@apple_support~1.5.0//crosstool:setup.bzl",
+ "ruleClassName": "_apple_cc_autoconf_toolchains",
+ "attributes": {
+ "name": "apple_support~1.5.0~apple_cc_configure_extension~local_config_apple_cc_toolchains"
+ }
+ }
+ },
+ "recordedRepoMappingEntries": [
+ [
+ "apple_support~1.5.0",
+ "bazel_tools",
+ "bazel_tools"
+ ]
+ ]
+ }
+ },
+ "@@bazel_tools//tools/cpp:cc_configure.bzl%cc_configure_extension": {
+ "general": {
+ "bzlTransitiveDigest": "mcsWHq3xORJexV5/4eCvNOLxFOQKV6eli3fkr+tEaqE=",
+ "accumulatedFileDigests": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "local_config_cc": {
+ "bzlFile": "@@bazel_tools//tools/cpp:cc_configure.bzl",
+ "ruleClassName": "cc_autoconf",
+ "attributes": {
+ "name": "bazel_tools~cc_configure_extension~local_config_cc"
+ }
+ },
+ "local_config_cc_toolchains": {
+ "bzlFile": "@@bazel_tools//tools/cpp:cc_configure.bzl",
+ "ruleClassName": "cc_autoconf_toolchains",
+ "attributes": {
+ "name": "bazel_tools~cc_configure_extension~local_config_cc_toolchains"
+ }
+ }
+ },
+ "recordedRepoMappingEntries": [
+ [
+ "bazel_tools",
+ "bazel_tools",
+ "bazel_tools"
+ ]
+ ]
+ }
+ },
+ "@@bazel_tools//tools/osx:xcode_configure.bzl%xcode_configure_extension": {
+ "general": {
+ "bzlTransitiveDigest": "Qh2bWTU6QW6wkrd87qrU4YeY+SG37Nvw3A0PR4Y0L2Y=",
+ "accumulatedFileDigests": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "local_config_xcode": {
+ "bzlFile": "@@bazel_tools//tools/osx:xcode_configure.bzl",
+ "ruleClassName": "xcode_autoconf",
+ "attributes": {
+ "name": "bazel_tools~xcode_configure_extension~local_config_xcode",
+ "xcode_locator": "@bazel_tools//tools/osx:xcode_locator.m",
+ "remote_xcode": ""
+ }
+ }
+ },
+ "recordedRepoMappingEntries": []
+ }
+ },
+ "@@bazel_tools//tools/sh:sh_configure.bzl%sh_configure_extension": {
+ "general": {
+ "bzlTransitiveDigest": "hp4NgmNjEg5+xgvzfh6L83bt9/aiiWETuNpwNuF1MSU=",
+ "accumulatedFileDigests": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "local_config_sh": {
+ "bzlFile": "@@bazel_tools//tools/sh:sh_configure.bzl",
+ "ruleClassName": "sh_config",
+ "attributes": {
+ "name": "bazel_tools~sh_configure_extension~local_config_sh"
+ }
+ }
+ },
+ "recordedRepoMappingEntries": []
+ }
+ },
+ "@@rules_java~7.1.0//java:extensions.bzl%toolchains": {
+ "general": {
+ "bzlTransitiveDigest": "D02GmifxnV/IhYgspsJMDZ/aE8HxAjXgek5gi6FSto4=",
+ "accumulatedFileDigests": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "remotejdk21_linux_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_linux_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_21\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"21\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk21_linux//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk21_linux//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk17_linux_s390x_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_linux_s390x_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_17\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"17\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:s390x\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk17_linux_s390x//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:s390x\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk17_linux_s390x//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk17_macos_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_macos_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_17\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"17\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk17_macos//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk17_macos//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk21_macos_aarch64_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_macos_aarch64_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_21\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"21\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk21_macos_aarch64//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk21_macos_aarch64//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk17_linux_aarch64_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_linux_aarch64_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_17\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"17\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk17_linux_aarch64//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk17_linux_aarch64//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk21_macos_aarch64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_macos_aarch64",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 21,\n)\n",
+ "sha256": "2a7a99a3ea263dbd8d32a67d1e6e363ba8b25c645c826f5e167a02bbafaff1fa",
+ "strip_prefix": "zulu21.28.85-ca-jdk21.0.0-macosx_aarch64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-macosx_aarch64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-macosx_aarch64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk17_linux_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_linux_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_17\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"17\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk17_linux//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk17_linux//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk17_macos_aarch64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_macos_aarch64",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 17,\n)\n",
+ "sha256": "314b04568ec0ae9b36ba03c9cbd42adc9e1265f74678923b19297d66eb84dcca",
+ "strip_prefix": "zulu17.44.53-ca-jdk17.0.8.1-macosx_aarch64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-macosx_aarch64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-macosx_aarch64.tar.gz"
+ ]
+ }
+ },
+ "remote_java_tools_windows": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remote_java_tools_windows",
+ "sha256": "c5c70c214a350f12cbf52da8270fa43ba629b795f3dd328028a38f8f0d39c2a1",
+ "urls": [
+ "https://mirror.bazel.build/bazel_java_tools/releases/java/v13.1/java_tools_windows-v13.1.zip",
+ "https://github.com/bazelbuild/java_tools/releases/download/java_v13.1/java_tools_windows-v13.1.zip"
+ ]
+ }
+ },
+ "remotejdk11_win": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_win",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 11,\n)\n",
+ "sha256": "43408193ce2fa0862819495b5ae8541085b95660153f2adcf91a52d3a1710e83",
+ "strip_prefix": "zulu11.66.15-ca-jdk11.0.20-win_x64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-win_x64.zip",
+ "https://cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-win_x64.zip"
+ ]
+ }
+ },
+ "remotejdk11_win_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_win_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_11\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"11\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk11_win//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk11_win//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk11_linux_aarch64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_linux_aarch64",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 11,\n)\n",
+ "sha256": "54174439f2b3fddd11f1048c397fe7bb45d4c9d66d452d6889b013d04d21c4de",
+ "strip_prefix": "zulu11.66.15-ca-jdk11.0.20-linux_aarch64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-linux_aarch64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-linux_aarch64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk17_linux": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_linux",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 17,\n)\n",
+ "sha256": "b9482f2304a1a68a614dfacddcf29569a72f0fac32e6c74f83dc1b9a157b8340",
+ "strip_prefix": "zulu17.44.53-ca-jdk17.0.8.1-linux_x64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-linux_x64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-linux_x64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk11_linux_s390x_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_linux_s390x_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_11\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"11\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:s390x\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk11_linux_s390x//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:s390x\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk11_linux_s390x//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk11_linux_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_linux_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_11\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"11\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk11_linux//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk11_linux//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk11_macos": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_macos",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 11,\n)\n",
+ "sha256": "bcaab11cfe586fae7583c6d9d311c64384354fb2638eb9a012eca4c3f1a1d9fd",
+ "strip_prefix": "zulu11.66.15-ca-jdk11.0.20-macosx_x64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-macosx_x64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-macosx_x64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk11_win_arm64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_win_arm64",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 11,\n)\n",
+ "sha256": "b8a28e6e767d90acf793ea6f5bed0bb595ba0ba5ebdf8b99f395266161e53ec2",
+ "strip_prefix": "jdk-11.0.13+8",
+ "urls": [
+ "https://mirror.bazel.build/aka.ms/download-jdk/microsoft-jdk-11.0.13.8.1-windows-aarch64.zip"
+ ]
+ }
+ },
+ "remotejdk17_macos": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_macos",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 17,\n)\n",
+ "sha256": "640453e8afe8ffe0fb4dceb4535fb50db9c283c64665eebb0ba68b19e65f4b1f",
+ "strip_prefix": "zulu17.44.53-ca-jdk17.0.8.1-macosx_x64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-macosx_x64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-macosx_x64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk21_macos": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_macos",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 21,\n)\n",
+ "sha256": "9639b87db586d0c89f7a9892ae47f421e442c64b97baebdff31788fbe23265bd",
+ "strip_prefix": "zulu21.28.85-ca-jdk21.0.0-macosx_x64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-macosx_x64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-macosx_x64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk21_macos_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_macos_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_21\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"21\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk21_macos//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk21_macos//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk17_macos_aarch64_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_macos_aarch64_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_17\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"17\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk17_macos_aarch64//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk17_macos_aarch64//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk17_win": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_win",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 17,\n)\n",
+ "sha256": "192f2afca57701de6ec496234f7e45d971bf623ff66b8ee4a5c81582054e5637",
+ "strip_prefix": "zulu17.44.53-ca-jdk17.0.8.1-win_x64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-win_x64.zip",
+ "https://cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-win_x64.zip"
+ ]
+ }
+ },
+ "remotejdk11_macos_aarch64_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_macos_aarch64_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_11\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"11\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk11_macos_aarch64//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk11_macos_aarch64//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk11_linux_ppc64le_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_linux_ppc64le_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_11\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"11\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:ppc\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk11_linux_ppc64le//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:ppc\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk11_linux_ppc64le//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk21_linux": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_linux",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 21,\n)\n",
+ "sha256": "0c0eadfbdc47a7ca64aeab51b9c061f71b6e4d25d2d87674512e9b6387e9e3a6",
+ "strip_prefix": "zulu21.28.85-ca-jdk21.0.0-linux_x64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-linux_x64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-linux_x64.tar.gz"
+ ]
+ }
+ },
+ "remote_java_tools_linux": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remote_java_tools_linux",
+ "sha256": "d134da9b04c9023fb6e56a5d4bffccee73f7bc9572ddc4e747778dacccd7a5a7",
+ "urls": [
+ "https://mirror.bazel.build/bazel_java_tools/releases/java/v13.1/java_tools_linux-v13.1.zip",
+ "https://github.com/bazelbuild/java_tools/releases/download/java_v13.1/java_tools_linux-v13.1.zip"
+ ]
+ }
+ },
+ "remotejdk21_win": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_win",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 21,\n)\n",
+ "sha256": "e9959d500a0d9a7694ac243baf657761479da132f0f94720cbffd092150bd802",
+ "strip_prefix": "zulu21.28.85-ca-jdk21.0.0-win_x64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-win_x64.zip",
+ "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-win_x64.zip"
+ ]
+ }
+ },
+ "remotejdk21_linux_aarch64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_linux_aarch64",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 21,\n)\n",
+ "sha256": "1fb64b8036c5d463d8ab59af06bf5b6b006811e6012e3b0eb6bccf57f1c55835",
+ "strip_prefix": "zulu21.28.85-ca-jdk21.0.0-linux_aarch64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-linux_aarch64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu21.28.85-ca-jdk21.0.0-linux_aarch64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk11_linux_aarch64_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_linux_aarch64_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_11\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"11\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk11_linux_aarch64//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk11_linux_aarch64//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk11_linux_s390x": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_linux_s390x",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 11,\n)\n",
+ "sha256": "a58fc0361966af0a5d5a31a2d8a208e3c9bb0f54f345596fd80b99ea9a39788b",
+ "strip_prefix": "jdk-11.0.15+10",
+ "urls": [
+ "https://mirror.bazel.build/github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15+10/OpenJDK11U-jdk_s390x_linux_hotspot_11.0.15_10.tar.gz",
+ "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15+10/OpenJDK11U-jdk_s390x_linux_hotspot_11.0.15_10.tar.gz"
+ ]
+ }
+ },
+ "remotejdk17_linux_aarch64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_linux_aarch64",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 17,\n)\n",
+ "sha256": "6531cef61e416d5a7b691555c8cf2bdff689201b8a001ff45ab6740062b44313",
+ "strip_prefix": "zulu17.44.53-ca-jdk17.0.8.1-linux_aarch64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-linux_aarch64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-linux_aarch64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk17_win_arm64_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_win_arm64_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_17\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"17\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:arm64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk17_win_arm64//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:arm64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk17_win_arm64//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk11_linux": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_linux",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 11,\n)\n",
+ "sha256": "a34b404f87a08a61148b38e1416d837189e1df7a040d949e743633daf4695a3c",
+ "strip_prefix": "zulu11.66.15-ca-jdk11.0.20-linux_x64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-linux_x64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-linux_x64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk11_macos_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_macos_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_11\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"11\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk11_macos//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:macos\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk11_macos//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk17_linux_ppc64le_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_linux_ppc64le_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_17\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"17\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:ppc\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk17_linux_ppc64le//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:ppc\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk17_linux_ppc64le//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk17_win_arm64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_win_arm64",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 17,\n)\n",
+ "sha256": "6802c99eae0d788e21f52d03cab2e2b3bf42bc334ca03cbf19f71eb70ee19f85",
+ "strip_prefix": "zulu17.44.53-ca-jdk17.0.8.1-win_aarch64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-win_aarch64.zip",
+ "https://cdn.azul.com/zulu/bin/zulu17.44.53-ca-jdk17.0.8.1-win_aarch64.zip"
+ ]
+ }
+ },
+ "remote_java_tools_darwin_arm64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remote_java_tools_darwin_arm64",
+ "sha256": "dab5bb87ec43e980faea6e1cec14bafb217b8e2f5346f53aa784fd715929a930",
+ "urls": [
+ "https://mirror.bazel.build/bazel_java_tools/releases/java/v13.1/java_tools_darwin_arm64-v13.1.zip",
+ "https://github.com/bazelbuild/java_tools/releases/download/java_v13.1/java_tools_darwin_arm64-v13.1.zip"
+ ]
+ }
+ },
+ "remotejdk17_linux_ppc64le": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_linux_ppc64le",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 17,\n)\n",
+ "sha256": "00a4c07603d0218cd678461b5b3b7e25b3253102da4022d31fc35907f21a2efd",
+ "strip_prefix": "jdk-17.0.8.1+1",
+ "urls": [
+ "https://mirror.bazel.build/github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.8.1%2B1/OpenJDK17U-jdk_ppc64le_linux_hotspot_17.0.8.1_1.tar.gz",
+ "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.8.1%2B1/OpenJDK17U-jdk_ppc64le_linux_hotspot_17.0.8.1_1.tar.gz"
+ ]
+ }
+ },
+ "remotejdk21_linux_aarch64_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_linux_aarch64_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_21\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"21\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk21_linux_aarch64//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:linux\", \"@platforms//cpu:aarch64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk21_linux_aarch64//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk11_win_arm64_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_win_arm64_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_11\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"11\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:arm64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk11_win_arm64//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:arm64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk11_win_arm64//:jdk\",\n)\n"
+ }
+ },
+ "local_jdk": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:local_java_repository.bzl",
+ "ruleClassName": "_local_java_repository_rule",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~local_jdk",
+ "java_home": "",
+ "version": "",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = {RUNTIME_VERSION},\n)\n"
+ }
+ },
+ "remote_java_tools_darwin_x86_64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remote_java_tools_darwin_x86_64",
+ "sha256": "0db40d8505a2b65ef0ed46e4256757807db8162f7acff16225be57c1d5726dbc",
+ "urls": [
+ "https://mirror.bazel.build/bazel_java_tools/releases/java/v13.1/java_tools_darwin_x86_64-v13.1.zip",
+ "https://github.com/bazelbuild/java_tools/releases/download/java_v13.1/java_tools_darwin_x86_64-v13.1.zip"
+ ]
+ }
+ },
+ "remote_java_tools": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remote_java_tools",
+ "sha256": "286bdbbd66e616fc4ed3f90101418729a73baa7e8c23a98ffbef558f74c0ad14",
+ "urls": [
+ "https://mirror.bazel.build/bazel_java_tools/releases/java/v13.1/java_tools-v13.1.zip",
+ "https://github.com/bazelbuild/java_tools/releases/download/java_v13.1/java_tools-v13.1.zip"
+ ]
+ }
+ },
+ "remotejdk17_linux_s390x": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_linux_s390x",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 17,\n)\n",
+ "sha256": "ffacba69c6843d7ca70d572489d6cc7ab7ae52c60f0852cedf4cf0d248b6fc37",
+ "strip_prefix": "jdk-17.0.8.1+1",
+ "urls": [
+ "https://mirror.bazel.build/github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.8.1%2B1/OpenJDK17U-jdk_s390x_linux_hotspot_17.0.8.1_1.tar.gz",
+ "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.8.1%2B1/OpenJDK17U-jdk_s390x_linux_hotspot_17.0.8.1_1.tar.gz"
+ ]
+ }
+ },
+ "remotejdk17_win_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk17_win_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_17\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"17\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk17_win//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk17_win//:jdk\",\n)\n"
+ }
+ },
+ "remotejdk11_linux_ppc64le": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_linux_ppc64le",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 11,\n)\n",
+ "sha256": "a8fba686f6eb8ae1d1a9566821dbd5a85a1108b96ad857fdbac5c1e4649fc56f",
+ "strip_prefix": "jdk-11.0.15+10",
+ "urls": [
+ "https://mirror.bazel.build/github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15+10/OpenJDK11U-jdk_ppc64le_linux_hotspot_11.0.15_10.tar.gz",
+ "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15+10/OpenJDK11U-jdk_ppc64le_linux_hotspot_11.0.15_10.tar.gz"
+ ]
+ }
+ },
+ "remotejdk11_macos_aarch64": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk11_macos_aarch64",
+ "build_file_content": "load(\"@rules_java//java:defs.bzl\", \"java_runtime\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files([\"WORKSPACE\", \"BUILD.bazel\"])\n\nfilegroup(\n name = \"jre\",\n srcs = glob(\n [\n \"jre/bin/**\",\n \"jre/lib/**\",\n ],\n allow_empty = True,\n # In some configurations, Java browser plugin is considered harmful and\n # common antivirus software blocks access to npjp2.dll interfering with Bazel,\n # so do not include it in JRE on Windows.\n exclude = [\"jre/bin/plugin2/**\"],\n ),\n)\n\nfilegroup(\n name = \"jdk-bin\",\n srcs = glob(\n [\"bin/**\"],\n # The JDK on Windows sometimes contains a directory called\n # \"%systemroot%\", which is not a valid label.\n exclude = [\"**/*%*/**\"],\n ),\n)\n\n# This folder holds security policies.\nfilegroup(\n name = \"jdk-conf\",\n srcs = glob(\n [\"conf/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-include\",\n srcs = glob(\n [\"include/**\"],\n allow_empty = True,\n ),\n)\n\nfilegroup(\n name = \"jdk-lib\",\n srcs = glob(\n [\"lib/**\", \"release\"],\n allow_empty = True,\n exclude = [\n \"lib/missioncontrol/**\",\n \"lib/visualvm/**\",\n ],\n ),\n)\n\njava_runtime(\n name = \"jdk\",\n srcs = [\n \":jdk-bin\",\n \":jdk-conf\",\n \":jdk-include\",\n \":jdk-lib\",\n \":jre\",\n ],\n # Provide the 'java` binary explicitly so that the correct path is used by\n # Bazel even when the host platform differs from the execution platform.\n # Exactly one of the two globs will be empty depending on the host platform.\n # When --incompatible_disallow_empty_glob is enabled, each individual empty\n # glob will fail without allow_empty = True, even if the overall result is\n # non-empty.\n java = glob([\"bin/java.exe\", \"bin/java\"], allow_empty = True)[0],\n version = 11,\n)\n",
+ "sha256": "7632bc29f8a4b7d492b93f3bc75a7b61630894db85d136456035ab2a24d38885",
+ "strip_prefix": "zulu11.66.15-ca-jdk11.0.20-macosx_aarch64",
+ "urls": [
+ "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-macosx_aarch64.tar.gz",
+ "https://cdn.azul.com/zulu/bin/zulu11.66.15-ca-jdk11.0.20-macosx_aarch64.tar.gz"
+ ]
+ }
+ },
+ "remotejdk21_win_toolchain_config_repo": {
+ "bzlFile": "@@rules_java~7.1.0//toolchains:remote_java_repository.bzl",
+ "ruleClassName": "_toolchain_config",
+ "attributes": {
+ "name": "rules_java~7.1.0~toolchains~remotejdk21_win_toolchain_config_repo",
+ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_21\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"21\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk21_win//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk21_win//:jdk\",\n)\n"
+ }
+ }
+ },
+ "recordedRepoMappingEntries": [
+ [
+ "rules_java~7.1.0",
+ "bazel_tools",
+ "bazel_tools"
+ ],
+ [
+ "rules_java~7.1.0",
+ "remote_java_tools",
+ "rules_java~7.1.0~toolchains~remote_java_tools"
+ ]
+ ]
+ }
+ },
+ "@@rules_python~0.31.0//python/extensions:python.bzl%python": {
+ "general": {
+ "bzlTransitiveDigest": "nfcQ92K2B0JOoUwqlGTKoGF7+XoHjDW/y8t8LMG8TE4=",
+ "accumulatedFileDigests": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "python_3_11_s390x-unknown-linux-gnu": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_11_s390x-unknown-linux-gnu",
+ "sha256": "49520e3ff494708020f306e30b0964f079170be83e956be4504f850557378a22",
+ "patches": [],
+ "platform": "s390x-unknown-linux-gnu",
+ "python_version": "3.11.7",
+ "release_filename": "20240107/cpython-3.11.7+20240107-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-s390x-unknown-linux-gnu-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_11_host": {
+ "bzlFile": "@@rules_python~0.31.0//python/private:toolchains_repo.bzl",
+ "ruleClassName": "host_toolchain",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_11_host",
+ "python_version": "3.11.7",
+ "user_repository_name": "python_3_11",
+ "platforms": [
+ "aarch64-apple-darwin",
+ "aarch64-unknown-linux-gnu",
+ "ppc64le-unknown-linux-gnu",
+ "s390x-unknown-linux-gnu",
+ "x86_64-apple-darwin",
+ "x86_64-pc-windows-msvc",
+ "x86_64-unknown-linux-gnu"
+ ]
+ }
+ },
+ "python_3_10_aarch64-apple-darwin": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_10_aarch64-apple-darwin",
+ "sha256": "fd027b1dedf1ea034cdaa272e91771bdf75ddef4c8653b05d224a0645aa2ca3c",
+ "patches": [],
+ "platform": "aarch64-apple-darwin",
+ "python_version": "3.10.13",
+ "release_filename": "20231002/cpython-3.10.13+20231002-aarch64-apple-darwin-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.10.13+20231002-aarch64-apple-darwin-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_10_x86_64-apple-darwin": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_10_x86_64-apple-darwin",
+ "sha256": "be0b19b6af1f7d8c667e5abef5505ad06cf72e5a11bb5844970c395a7e5b1275",
+ "patches": [],
+ "platform": "x86_64-apple-darwin",
+ "python_version": "3.10.13",
+ "release_filename": "20231002/cpython-3.10.13+20231002-x86_64-apple-darwin-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.10.13+20231002-x86_64-apple-darwin-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_11_aarch64-unknown-linux-gnu": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_11_aarch64-unknown-linux-gnu",
+ "sha256": "b102eaf865eb715aa98a8a2ef19037b6cc3ae7dfd4a632802650f29de635aa13",
+ "patches": [],
+ "platform": "aarch64-unknown-linux-gnu",
+ "python_version": "3.11.7",
+ "release_filename": "20240107/cpython-3.11.7+20240107-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-aarch64-unknown-linux-gnu-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_11_aarch64-apple-darwin": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_11_aarch64-apple-darwin",
+ "sha256": "b042c966920cf8465385ca3522986b12d745151a72c060991088977ca36d3883",
+ "patches": [],
+ "platform": "aarch64-apple-darwin",
+ "python_version": "3.11.7",
+ "release_filename": "20240107/cpython-3.11.7+20240107-aarch64-apple-darwin-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-aarch64-apple-darwin-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_10_ppc64le-unknown-linux-gnu": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_10_ppc64le-unknown-linux-gnu",
+ "sha256": "f3f9c43eec1a0c3f72845d0b705da17a336d3906b7df212d2640b8f47e8ff375",
+ "patches": [],
+ "platform": "ppc64le-unknown-linux-gnu",
+ "python_version": "3.10.13",
+ "release_filename": "20231002/cpython-3.10.13+20231002-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.10.13+20231002-ppc64le-unknown-linux-gnu-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_10_x86_64-pc-windows-msvc": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_10_x86_64-pc-windows-msvc",
+ "sha256": "b8d930ce0d04bda83037ad3653d7450f8907c88e24bb8255a29b8dab8930d6f1",
+ "patches": [],
+ "platform": "x86_64-pc-windows-msvc",
+ "python_version": "3.10.13",
+ "release_filename": "20231002/cpython-3.10.13+20231002-x86_64-pc-windows-msvc-shared-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.10.13+20231002-x86_64-pc-windows-msvc-shared-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "pythons_hub": {
+ "bzlFile": "@@rules_python~0.31.0//python/private/bzlmod:pythons_hub.bzl",
+ "ruleClassName": "hub_repo",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~pythons_hub",
+ "default_python_version": "3.10",
+ "toolchain_prefixes": [
+ "_0000_python_3_11_",
+ "_0001_python_3_10_"
+ ],
+ "toolchain_python_versions": [
+ "3.11",
+ "3.10"
+ ],
+ "toolchain_set_python_version_constraints": [
+ "True",
+ "False"
+ ],
+ "toolchain_user_repository_names": [
+ "python_3_11",
+ "python_3_10"
+ ]
+ }
+ },
+ "python_3_11_x86_64-pc-windows-msvc": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_11_x86_64-pc-windows-msvc",
+ "sha256": "67077e6fa918e4f4fd60ba169820b00be7c390c497bf9bc9cab2c255ea8e6f3e",
+ "patches": [],
+ "platform": "x86_64-pc-windows-msvc",
+ "python_version": "3.11.7",
+ "release_filename": "20240107/cpython-3.11.7+20240107-x86_64-pc-windows-msvc-shared-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-x86_64-pc-windows-msvc-shared-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_10_aarch64-unknown-linux-gnu": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_10_aarch64-unknown-linux-gnu",
+ "sha256": "8675915ff454ed2f1597e27794bc7df44f5933c26b94aa06af510fe91b58bb97",
+ "patches": [],
+ "platform": "aarch64-unknown-linux-gnu",
+ "python_version": "3.10.13",
+ "release_filename": "20231002/cpython-3.10.13+20231002-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.10.13+20231002-aarch64-unknown-linux-gnu-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_11": {
+ "bzlFile": "@@rules_python~0.31.0//python/private:toolchains_repo.bzl",
+ "ruleClassName": "toolchain_aliases",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_11",
+ "python_version": "3.11.7",
+ "user_repository_name": "python_3_11",
+ "platforms": [
+ "aarch64-apple-darwin",
+ "aarch64-unknown-linux-gnu",
+ "ppc64le-unknown-linux-gnu",
+ "s390x-unknown-linux-gnu",
+ "x86_64-apple-darwin",
+ "x86_64-pc-windows-msvc",
+ "x86_64-unknown-linux-gnu"
+ ]
+ }
+ },
+ "python_3_10_s390x-unknown-linux-gnu": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_10_s390x-unknown-linux-gnu",
+ "sha256": "859f6cfe9aedb6e8858892fdc124037e83ab05f28d42a7acd314c6a16d6bd66c",
+ "patches": [],
+ "platform": "s390x-unknown-linux-gnu",
+ "python_version": "3.10.13",
+ "release_filename": "20231002/cpython-3.10.13+20231002-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.10.13+20231002-s390x-unknown-linux-gnu-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_10": {
+ "bzlFile": "@@rules_python~0.31.0//python/private:toolchains_repo.bzl",
+ "ruleClassName": "toolchain_aliases",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_10",
+ "python_version": "3.10.13",
+ "user_repository_name": "python_3_10",
+ "platforms": [
+ "aarch64-apple-darwin",
+ "aarch64-unknown-linux-gnu",
+ "ppc64le-unknown-linux-gnu",
+ "s390x-unknown-linux-gnu",
+ "x86_64-apple-darwin",
+ "x86_64-pc-windows-msvc",
+ "x86_64-unknown-linux-gnu"
+ ]
+ }
+ },
+ "python_3_11_ppc64le-unknown-linux-gnu": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_11_ppc64le-unknown-linux-gnu",
+ "sha256": "b44e1b74afe75c7b19143413632c4386708ae229117f8f950c2094e9681d34c7",
+ "patches": [],
+ "platform": "ppc64le-unknown-linux-gnu",
+ "python_version": "3.11.7",
+ "release_filename": "20240107/cpython-3.11.7+20240107-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-ppc64le-unknown-linux-gnu-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_11_x86_64-apple-darwin": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_11_x86_64-apple-darwin",
+ "sha256": "a0e615eef1fafdc742da0008425a9030b7ea68a4ae4e73ac557ef27b112836d4",
+ "patches": [],
+ "platform": "x86_64-apple-darwin",
+ "python_version": "3.11.7",
+ "release_filename": "20240107/cpython-3.11.7+20240107-x86_64-apple-darwin-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-x86_64-apple-darwin-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_versions": {
+ "bzlFile": "@@rules_python~0.31.0//python/private:toolchains_repo.bzl",
+ "ruleClassName": "multi_toolchain_aliases",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_versions",
+ "python_versions": {
+ "3.10": "python_3_10",
+ "3.11": "python_3_11"
+ }
+ }
+ },
+ "python_3_10_x86_64-unknown-linux-gnu": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_10_x86_64-unknown-linux-gnu",
+ "sha256": "5d0429c67c992da19ba3eb58b3acd0b35ec5e915b8cae9a4aa8ca565c423847a",
+ "patches": [],
+ "platform": "x86_64-unknown-linux-gnu",
+ "python_version": "3.10.13",
+ "release_filename": "20231002/cpython-3.10.13+20231002-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.10.13+20231002-x86_64-unknown-linux-gnu-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ },
+ "python_3_10_host": {
+ "bzlFile": "@@rules_python~0.31.0//python/private:toolchains_repo.bzl",
+ "ruleClassName": "host_toolchain",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_10_host",
+ "python_version": "3.10.13",
+ "user_repository_name": "python_3_10",
+ "platforms": [
+ "aarch64-apple-darwin",
+ "aarch64-unknown-linux-gnu",
+ "ppc64le-unknown-linux-gnu",
+ "s390x-unknown-linux-gnu",
+ "x86_64-apple-darwin",
+ "x86_64-pc-windows-msvc",
+ "x86_64-unknown-linux-gnu"
+ ]
+ }
+ },
+ "python_3_11_x86_64-unknown-linux-gnu": {
+ "bzlFile": "@@rules_python~0.31.0//python:repositories.bzl",
+ "ruleClassName": "python_repository",
+ "attributes": {
+ "name": "rules_python~0.31.0~python~python_3_11_x86_64-unknown-linux-gnu",
+ "sha256": "4a51ce60007a6facf64e5495f4cf322e311ba9f39a8cd3f3e4c026eae488e140",
+ "patches": [],
+ "platform": "x86_64-unknown-linux-gnu",
+ "python_version": "3.11.7",
+ "release_filename": "20240107/cpython-3.11.7+20240107-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "urls": [
+ "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-x86_64-unknown-linux-gnu-install_only.tar.gz"
+ ],
+ "distutils_content": "",
+ "strip_prefix": "python",
+ "coverage_tool": "",
+ "ignore_root_user_error": false
+ }
+ }
+ },
+ "recordedRepoMappingEntries": [
+ [
+ "rules_python~0.31.0",
+ "bazel_skylib",
+ "bazel_skylib~1.5.0"
+ ],
+ [
+ "rules_python~0.31.0",
+ "bazel_tools",
+ "bazel_tools"
+ ]
+ ]
+ }
+ },
+ "@@rules_python~0.31.0//python/private/bzlmod:internal_deps.bzl%internal_deps": {
+ "general": {
+ "bzlTransitiveDigest": "YM6cXp9AuQVARYWBY5VPn25r/wLyW6Lq09HCAiVNngE=",
+ "accumulatedFileDigests": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "pypi__wheel": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__wheel",
+ "url": "https://files.pythonhosted.org/packages/b8/8b/31273bf66016be6ad22bb7345c37ff350276cfd46e389a0c2ac5da9d9073/wheel-0.41.2-py3-none-any.whl",
+ "sha256": "75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__click": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__click",
+ "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl",
+ "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__importlib_metadata": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__importlib_metadata",
+ "url": "https://files.pythonhosted.org/packages/cc/37/db7ba97e676af155f5fcb1a35466f446eadc9104e25b83366e8088c9c926/importlib_metadata-6.8.0-py3-none-any.whl",
+ "sha256": "3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__pyproject_hooks": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__pyproject_hooks",
+ "url": "https://files.pythonhosted.org/packages/d5/ea/9ae603de7fbb3df820b23a70f6aff92bf8c7770043254ad8d2dc9d6bcba4/pyproject_hooks-1.0.0-py3-none-any.whl",
+ "sha256": "283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__pep517": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__pep517",
+ "url": "https://files.pythonhosted.org/packages/ee/2f/ef63e64e9429111e73d3d6cbee80591672d16f2725e648ebc52096f3d323/pep517-0.13.0-py3-none-any.whl",
+ "sha256": "4ba4446d80aed5b5eac6509ade100bff3e7943a8489de249654a5ae9b33ee35b",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__packaging": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__packaging",
+ "url": "https://files.pythonhosted.org/packages/ab/c3/57f0601a2d4fe15de7a553c00adbc901425661bf048f2a22dfc500caf121/packaging-23.1-py3-none-any.whl",
+ "sha256": "994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__pip_tools": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__pip_tools",
+ "url": "https://files.pythonhosted.org/packages/e8/df/47e6267c6b5cdae867adbdd84b437393e6202ce4322de0a5e0b92960e1d6/pip_tools-7.3.0-py3-none-any.whl",
+ "sha256": "8717693288720a8c6ebd07149c93ab0be1fced0b5191df9e9decd3263e20d85e",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__setuptools": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__setuptools",
+ "url": "https://files.pythonhosted.org/packages/4f/ab/0bcfebdfc3bfa8554b2b2c97a555569c4c1ebc74ea288741ea8326c51906/setuptools-68.1.2-py3-none-any.whl",
+ "sha256": "3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__zipp": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__zipp",
+ "url": "https://files.pythonhosted.org/packages/8c/08/d3006317aefe25ea79d3b76c9650afabaf6d63d1c8443b236e7405447503/zipp-3.16.2-py3-none-any.whl",
+ "sha256": "679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__colorama": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__colorama",
+ "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl",
+ "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__build": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__build",
+ "url": "https://files.pythonhosted.org/packages/58/91/17b00d5fac63d3dca605f1b8269ba3c65e98059e1fd99d00283e42a454f0/build-0.10.0-py3-none-any.whl",
+ "sha256": "af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "rules_python_internal": {
+ "bzlFile": "@@rules_python~0.31.0//python/private:internal_config_repo.bzl",
+ "ruleClassName": "internal_config_repo",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~rules_python_internal"
+ }
+ },
+ "pypi__pip": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__pip",
+ "url": "https://files.pythonhosted.org/packages/50/c2/e06851e8cc28dcad7c155f4753da8833ac06a5c704c109313b8d5a62968a/pip-23.2.1-py3-none-any.whl",
+ "sha256": "7ccf472345f20d35bdc9d1841ff5f313260c2c33fe417f48c30ac46cccabf5be",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__installer": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__installer",
+ "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl",
+ "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__more_itertools": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__more_itertools",
+ "url": "https://files.pythonhosted.org/packages/5a/cb/6dce742ea14e47d6f565589e859ad225f2a5de576d7696e0623b784e226b/more_itertools-10.1.0-py3-none-any.whl",
+ "sha256": "64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ },
+ "pypi__tomli": {
+ "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
+ "ruleClassName": "http_archive",
+ "attributes": {
+ "name": "rules_python~0.31.0~internal_deps~pypi__tomli",
+ "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl",
+ "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
+ "type": "zip",
+ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
+ }
+ }
+ },
+ "recordedRepoMappingEntries": [
+ [
+ "rules_python~0.31.0",
+ "bazel_tools",
+ "bazel_tools"
+ ]
+ ]
+ }
+ }
+ }
+}
diff --git a/WORKSPACE b/WORKSPACE
index c1ff813..0976905 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -4,42 +4,6 @@ workspace(
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-http_archive(
- name = "rules_python",
- sha256 = "a868059c8c6dd6ad45a205cca04084c652cfe1852e6df2d5aca036f6e5438380",
- strip_prefix = "rules_python-0.14.0",
- url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.14.0.tar.gz",
-)
-
-load("@rules_python//python:repositories.bzl", "python_register_toolchains")
-
-python_register_toolchains(
- name = "python3_10",
- # Available versions are listed in @rules_python//python:versions.bzl.
- # We recommend using the same version your team is already standardized on.
- python_version = "3.10.6",
-)
-
-load("@python3_10//:defs.bzl", "interpreter")
-load("@rules_python//python:pip.bzl", "pip_parse")
-
-pip_parse(
- name = "py_proto_deps",
- python_interpreter_target = interpreter,
- requirements_lock = "//src:requirements.txt",
-)
-
-http_archive(
- name = "bazel_skylib",
- sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44",
- urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
- "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
- ],
-)
-
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
http_archive(
name = "com_google_protobuf",
build_file_content = """