├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── OWNERS ├── README.md ├── __init__.py ├── doc ├── API.md ├── STL.md └── html │ ├── abc.ABCMeta-class.html │ ├── api-objects.txt │ ├── class-tree.html │ ├── crarr.png │ ├── epydoc.css │ ├── epydoc.js │ ├── exceptions.AssertionError-class.html │ ├── frames.html │ ├── google.protobuf.reflection.GeneratedProtocolMessageType-class.html │ ├── help.html │ ├── identifier-index.html │ ├── index.html │ ├── module-tree.html │ ├── redirect.html │ ├── sprockets-module.html │ ├── sprockets-pysrc.html │ ├── sprockets.example-module.html │ ├── sprockets.example-pysrc.html │ ├── sprockets.example.example_lib-module.html │ ├── sprockets.example.example_lib-pysrc.html │ ├── sprockets.example.example_lib.KeyValueEncoding-class.html │ ├── sprockets.example.example_test-module.html │ ├── sprockets.example.example_test-pysrc.html │ ├── sprockets.example.example_test.KeyValueEncodingTestCase-class.html │ ├── sprockets.example.noop-module.html │ ├── sprockets.example.noop-pysrc.html │ ├── sprockets.example.noop.LogEncodedParams-class.html │ ├── sprockets.example.noop.LogParams-class.html │ ├── sprockets.example.noop.NoOp-class.html │ ├── sprockets.example.noop.Sleep-class.html │ ├── sprockets.example.proto-module.html │ ├── sprockets.example.proto-pysrc.html │ ├── sprockets.example.proto.example_pb2-module.html │ ├── sprockets.example.proto.example_pb2-pysrc.html │ ├── sprockets.example.proto.example_pb2.SimpleMsg-class.html │ ├── sprockets.example.run_test-module.html │ ├── sprockets.example.run_test-pysrc.html │ ├── sprockets.stl-module.html │ ├── sprockets.stl-pysrc.html │ ├── sprockets.stl.base-module.html │ ├── sprockets.stl.base-pysrc.html │ ├── sprockets.stl.base.Const-class.html │ ├── sprockets.stl.base.Expand-class.html │ ├── sprockets.stl.base.Field-class.html │ ├── sprockets.stl.base.Func-class.html │ ├── sprockets.stl.base.FuncGetField-class.html │ ├── sprockets.stl.base.FuncNoOp-class.html │ ├── sprockets.stl.base.FuncSet-class.html │ ├── sprockets.stl.base.FuncWithContext-class.html │ ├── sprockets.stl.base.FuncWithContext.Context-class.html │ ├── sprockets.stl.base.LocalVar-class.html │ ├── sprockets.stl.base.NamedObject-class.html │ ├── sprockets.stl.base.Param-class.html │ ├── sprockets.stl.base.ParameterizedObject-class.html │ ├── sprockets.stl.base.QualifierValue-class.html │ ├── sprockets.stl.base.QualifierValue.Resolved-class.html │ ├── sprockets.stl.base.Role-class.html │ ├── sprockets.stl.base.TypedObject-class.html │ ├── sprockets.stl.base.Value-class.html │ ├── sprockets.stl.base_test-module.html │ ├── sprockets.stl.base_test-pysrc.html │ ├── sprockets.stl.base_test.BaseTest-class.html │ ├── sprockets.stl.event-module.html │ ├── sprockets.stl.event-pysrc.html │ ├── sprockets.stl.event.Event-class.html │ ├── sprockets.stl.event.EventFromExternal-class.html │ ├── sprockets.stl.event.EventInTransition-class.html │ ├── sprockets.stl.graph-module.html │ ├── sprockets.stl.graph-pysrc.html │ ├── sprockets.stl.graph.StateVertex-class.html │ ├── sprockets.stl.graph.TransitionEdge-class.html │ ├── sprockets.stl.lib-module.html │ ├── sprockets.stl.lib-pysrc.html │ ├── sprockets.stl.lib.AnyOf-class.html │ ├── sprockets.stl.lib.DifferentFrom-class.html │ ├── sprockets.stl.lib.Encoding-class.html │ ├── sprockets.stl.lib.Event-class.html │ ├── sprockets.stl.lib.JsonEncoding-class.html │ ├── sprockets.stl.lib.ProtobufBase64Encoding-class.html │ ├── sprockets.stl.lib.ProtobufEncoding-class.html │ ├── sprockets.stl.lib.Qualifier-class.html │ ├── sprockets.stl.lib.RandomBool-class.html │ ├── sprockets.stl.lib.RandomString-class.html │ ├── sprockets.stl.lib.UniqueInt-class.html │ ├── sprockets.stl.lib.UniqueString-class.html │ ├── sprockets.stl.message-module.html │ ├── sprockets.stl.message-pysrc.html │ ├── sprockets.stl.message.Message-class.html │ ├── sprockets.stl.message.MessageFromExternal-class.html │ ├── sprockets.stl.message.MessageValue-class.html │ ├── sprockets.stl.message_test-module.html │ ├── sprockets.stl.message_test-pysrc.html │ ├── sprockets.stl.message_test.MessageTest-class.html │ ├── sprockets.stl.parser-module.html │ ├── sprockets.stl.parser-pysrc.html │ ├── sprockets.stl.parser.StlSyntaxError-class.html │ ├── sprockets.stl.parser_test-module.html │ ├── sprockets.stl.parser_test-pysrc.html │ ├── sprockets.stl.parser_test.StlParserTest-class.html │ ├── sprockets.stl.parser_test_proto_pb2-module.html │ ├── sprockets.stl.parser_test_proto_pb2-pysrc.html │ ├── sprockets.stl.parser_test_proto_pb2.SimpleMsg-class.html │ ├── sprockets.stl.qualifier-module.html │ ├── sprockets.stl.qualifier-pysrc.html │ ├── sprockets.stl.qualifier.Qualifier-class.html │ ├── sprockets.stl.qualifier.QualifierFromExternal-class.html │ ├── sprockets.stl.state-module.html │ ├── sprockets.stl.state-pysrc.html │ ├── sprockets.stl.state.State-class.html │ ├── sprockets.stl.state.StateResolved-class.html │ ├── sprockets.stl.state.StateValue-class.html │ ├── sprockets.stl.state.StateValueInTransition-class.html │ ├── sprockets.stl.state.Transition-class.html │ ├── sprockets.stl.state_test-module.html │ ├── sprockets.stl.state_test-pysrc.html │ ├── sprockets.stl.state_test.StateTest-class.html │ ├── sprockets.stl.traverse-module.html │ ├── sprockets.stl.traverse-pysrc.html │ ├── sprockets.stl.traverse.Context-class.html │ ├── sprockets.test_driver-module.html │ ├── sprockets.test_driver-pysrc.html │ ├── test.sprockets-module.html │ ├── test.sprockets-pysrc.html │ ├── test.sprockets.example-module.html │ ├── test.sprockets.example-pysrc.html │ ├── test.sprockets.example.example_lib-module.html │ ├── test.sprockets.example.example_lib-pysrc.html │ ├── test.sprockets.example.example_lib.KeyValueEncoding-class.html │ ├── test.sprockets.example.example_test-module.html │ ├── test.sprockets.example.example_test-pysrc.html │ ├── test.sprockets.example.example_test.KeyValueEncodingTestCase-class.html │ ├── test.sprockets.example.noop-module.html │ ├── test.sprockets.example.noop-pysrc.html │ ├── test.sprockets.example.noop.LogEncodedParams-class.html │ ├── test.sprockets.example.noop.LogParams-class.html │ ├── test.sprockets.example.noop.NoOp-class.html │ ├── test.sprockets.example.noop.Sleep-class.html │ ├── test.sprockets.example.proto-module.html │ ├── test.sprockets.example.proto-pysrc.html │ ├── test.sprockets.example.proto.example_pb2-module.html │ ├── test.sprockets.example.proto.example_pb2-pysrc.html │ ├── test.sprockets.example.proto.example_pb2.SimpleMsg-class.html │ ├── test.sprockets.example.run_test-module.html │ ├── test.sprockets.example.run_test-pysrc.html │ ├── test.sprockets.stl-module.html │ ├── test.sprockets.stl-pysrc.html │ ├── test.sprockets.stl.base-module.html │ ├── test.sprockets.stl.base-pysrc.html │ ├── test.sprockets.stl.base.Const-class.html │ ├── test.sprockets.stl.base.Expand-class.html │ ├── test.sprockets.stl.base.Field-class.html │ ├── test.sprockets.stl.base.Func-class.html │ ├── test.sprockets.stl.base.FuncGetField-class.html │ ├── test.sprockets.stl.base.FuncNoOp-class.html │ ├── test.sprockets.stl.base.FuncSet-class.html │ ├── test.sprockets.stl.base.FuncWithContext-class.html │ ├── test.sprockets.stl.base.FuncWithContext.Context-class.html │ ├── test.sprockets.stl.base.LocalVar-class.html │ ├── test.sprockets.stl.base.NamedObject-class.html │ ├── test.sprockets.stl.base.Param-class.html │ ├── test.sprockets.stl.base.ParameterizedObject-class.html │ ├── test.sprockets.stl.base.QualifierValue-class.html │ ├── test.sprockets.stl.base.QualifierValue.Resolved-class.html │ ├── test.sprockets.stl.base.Role-class.html │ ├── test.sprockets.stl.base.TypedObject-class.html │ ├── test.sprockets.stl.base.Value-class.html │ ├── test.sprockets.stl.base_test-module.html │ ├── test.sprockets.stl.base_test-pysrc.html │ ├── test.sprockets.stl.base_test.BaseTest-class.html │ ├── test.sprockets.stl.event-module.html │ ├── test.sprockets.stl.event-pysrc.html │ ├── test.sprockets.stl.event.Event-class.html │ ├── test.sprockets.stl.event.EventFromExternal-class.html │ ├── test.sprockets.stl.event.EventInTransition-class.html │ ├── test.sprockets.stl.graph-module.html │ ├── test.sprockets.stl.graph-pysrc.html │ ├── test.sprockets.stl.graph.StateVertex-class.html │ ├── test.sprockets.stl.graph.TransitionEdge-class.html │ ├── test.sprockets.stl.lib-module.html │ ├── test.sprockets.stl.lib-pysrc.html │ ├── test.sprockets.stl.lib.AnyOf-class.html │ ├── test.sprockets.stl.lib.DifferentFrom-class.html │ ├── test.sprockets.stl.lib.Encoding-class.html │ ├── test.sprockets.stl.lib.Event-class.html │ ├── test.sprockets.stl.lib.JsonEncoding-class.html │ ├── test.sprockets.stl.lib.ProtobufBase64Encoding-class.html │ ├── test.sprockets.stl.lib.ProtobufEncoding-class.html │ ├── test.sprockets.stl.lib.Qualifier-class.html │ ├── test.sprockets.stl.lib.RandomBool-class.html │ ├── test.sprockets.stl.lib.RandomString-class.html │ ├── test.sprockets.stl.lib.UniqueInt-class.html │ ├── test.sprockets.stl.lib.UniqueString-class.html │ ├── test.sprockets.stl.message-module.html │ ├── test.sprockets.stl.message-pysrc.html │ ├── test.sprockets.stl.message.Message-class.html │ ├── test.sprockets.stl.message.MessageFromExternal-class.html │ ├── test.sprockets.stl.message.MessageValue-class.html │ ├── test.sprockets.stl.message_test-module.html │ ├── test.sprockets.stl.message_test-pysrc.html │ ├── test.sprockets.stl.message_test.MessageTest-class.html │ ├── test.sprockets.stl.parser-module.html │ ├── test.sprockets.stl.parser-pysrc.html │ ├── test.sprockets.stl.parser.StlSyntaxError-class.html │ ├── test.sprockets.stl.parser_test-module.html │ ├── test.sprockets.stl.parser_test-pysrc.html │ ├── test.sprockets.stl.parser_test.StlParserTest-class.html │ ├── test.sprockets.stl.parser_test_proto_pb2-module.html │ ├── test.sprockets.stl.parser_test_proto_pb2-pysrc.html │ ├── test.sprockets.stl.parser_test_proto_pb2.SimpleMsg-class.html │ ├── test.sprockets.stl.qualifier-module.html │ ├── test.sprockets.stl.qualifier-pysrc.html │ ├── test.sprockets.stl.qualifier.Qualifier-class.html │ ├── test.sprockets.stl.qualifier.QualifierFromExternal-class.html │ ├── test.sprockets.stl.state-module.html │ ├── test.sprockets.stl.state-pysrc.html │ ├── test.sprockets.stl.state.State-class.html │ ├── test.sprockets.stl.state.StateResolved-class.html │ ├── test.sprockets.stl.state.StateValue-class.html │ ├── test.sprockets.stl.state.StateValueInTransition-class.html │ ├── test.sprockets.stl.state.Transition-class.html │ ├── test.sprockets.stl.state_test-module.html │ ├── test.sprockets.stl.state_test-pysrc.html │ ├── test.sprockets.stl.state_test.StateTest-class.html │ ├── test.sprockets.stl.traverse-module.html │ ├── test.sprockets.stl.traverse-pysrc.html │ ├── test.sprockets.stl.traverse.Context-class.html │ ├── test.sprockets.test_driver-module.html │ ├── test.sprockets.test_driver-pysrc.html │ ├── toc-everything.html │ ├── toc-sprockets-module.html │ ├── toc-sprockets.example-module.html │ ├── toc-sprockets.example.example_lib-module.html │ ├── toc-sprockets.example.example_test-module.html │ ├── toc-sprockets.example.noop-module.html │ ├── toc-sprockets.example.proto-module.html │ ├── toc-sprockets.example.proto.example_pb2-module.html │ ├── toc-sprockets.example.run_test-module.html │ ├── toc-sprockets.stl-module.html │ ├── toc-sprockets.stl.base-module.html │ ├── toc-sprockets.stl.base_test-module.html │ ├── toc-sprockets.stl.event-module.html │ ├── toc-sprockets.stl.graph-module.html │ ├── toc-sprockets.stl.lib-module.html │ ├── toc-sprockets.stl.message-module.html │ ├── toc-sprockets.stl.message_test-module.html │ ├── toc-sprockets.stl.parser-module.html │ ├── toc-sprockets.stl.parser_test-module.html │ ├── toc-sprockets.stl.parser_test_proto_pb2-module.html │ ├── toc-sprockets.stl.qualifier-module.html │ ├── toc-sprockets.stl.state-module.html │ ├── toc-sprockets.stl.state_test-module.html │ ├── toc-sprockets.stl.traverse-module.html │ ├── toc-sprockets.test_driver-module.html │ ├── toc-test.sprockets-module.html │ ├── toc-test.sprockets.example-module.html │ ├── toc-test.sprockets.example.example_lib-module.html │ ├── toc-test.sprockets.example.example_test-module.html │ ├── toc-test.sprockets.example.noop-module.html │ ├── toc-test.sprockets.example.proto-module.html │ ├── toc-test.sprockets.example.proto.example_pb2-module.html │ ├── toc-test.sprockets.example.run_test-module.html │ ├── toc-test.sprockets.stl-module.html │ ├── toc-test.sprockets.stl.base-module.html │ ├── toc-test.sprockets.stl.base_test-module.html │ ├── toc-test.sprockets.stl.event-module.html │ ├── toc-test.sprockets.stl.graph-module.html │ ├── toc-test.sprockets.stl.lib-module.html │ ├── toc-test.sprockets.stl.message-module.html │ ├── toc-test.sprockets.stl.message_test-module.html │ ├── toc-test.sprockets.stl.parser-module.html │ ├── toc-test.sprockets.stl.parser_test-module.html │ ├── toc-test.sprockets.stl.parser_test_proto_pb2-module.html │ ├── toc-test.sprockets.stl.qualifier-module.html │ ├── toc-test.sprockets.stl.state-module.html │ ├── toc-test.sprockets.stl.state_test-module.html │ ├── toc-test.sprockets.stl.traverse-module.html │ ├── toc-test.sprockets.test_driver-module.html │ └── toc.html ├── editor_support ├── sublime-text │ ├── README.md │ └── stl.YAML-tmLanguage └── vim │ ├── README.md │ ├── ftdetect │ └── stl.vim │ └── syntax │ └── stl.vim ├── end_to_end_test_data ├── did_you_mean_state_value.stl ├── did_you_mean_state_value.test ├── did_you_mean_transition.stl ├── did_you_mean_transition.test ├── noop.py ├── simple_example.stl └── simple_example.test ├── example ├── __init__.py ├── example.stl ├── example.test ├── example_base.stl ├── example_lib.py ├── example_test.py ├── noop.py ├── proto │ ├── __init__.py │ ├── example.proto │ └── example_pb2.py └── test_runner.py ├── gui ├── __init__.py ├── gui_server.py ├── html │ └── main.html ├── web_server.py └── websocket_server.py ├── requirements.txt ├── sprockets_end_to_end_test.py ├── stl ├── __init__.py ├── base.py ├── base_test.py ├── error_formatter.py ├── error_handler.py ├── event.py ├── graph.py ├── levenshtein.py ├── levenshtein_test.py ├── lexer.py ├── lexer_error.py ├── lib.py ├── message.py ├── message_test.py ├── module.py ├── parser.py ├── parser_error.py ├── parser_error_test.py ├── parser_test.py ├── parser_test_proto.proto ├── parser_test_proto_pb2.py ├── qualifier.py ├── state.py ├── state_test.py └── traverse.py └── test_driver.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.png 2 | *.pyc 3 | parser.out 4 | parsetab.py 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | sudo: required 3 | python: 4 | - "3.4" 5 | 6 | before-install: 7 | - sudo apt-get -qq update 8 | - sudo apt-get install -y libgraphviz-dev 9 | 10 | install: 11 | - pip install -r requirements.txt 12 | 13 | script: 14 | - python -m unittest discover --start-directory stl/ --pattern "*_test.py" 15 | - python -m unittest discover --start-directory example/ --pattern "*_test.py" 16 | - python sprockets_end_to_end_test.py 17 | 18 | notification: 19 | email: 20 | - sprockets-eng@googlegroups.com 21 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are a 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to any Google project must be accompanied by a Contributor License 9 | Agreement. This is necessary because you own the copyright to your changes, even 10 | after your contribution becomes part of this project. So this agreement simply 11 | gives us permission to use and redistribute your contributions as part of the 12 | project. Head over to to see your current 13 | agreements on file or to sign a new one. 14 | 15 | You generally only need to submit a CLA once, so if you've already submitted one 16 | (even if it was for a different project), you probably don't need to do it 17 | again. 18 | 19 | ## Code reviews 20 | 21 | All submissions, including submissions by project members, require review. We 22 | use GitHub pull requests for this purpose. Consult [GitHub Help] for more 23 | information on using pull requests. 24 | 25 | [GitHub Help]: https://help.github.com/articles/about-pull-requests/ 26 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | byungchul@google.com 2 | esum@google.com 3 | mbjorge@google.com 4 | seantopping@google.com 5 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/sprockets/6d551a413dc7daed594439f6ab2fab4e91c4473f/__init__.py -------------------------------------------------------------------------------- /doc/API.md: -------------------------------------------------------------------------------- 1 | # API to define builtin events and functions 2 | *Last updated at 2017-02-27* 3 | 4 | ## 1. Python API Documentation 5 | Documentation for various Sprockets Python modules is located at ```$PROJECT_ROOT/doc/html/index.html```. Up-to-date documentation can be viewed [here](https://htmlpreview.github.io/?https://github.com/google/sprockets/blob/master/doc/html/index.html). 6 | 7 | User-defined abstract classes (events, qualifiers, encodings, etc) are defined in the ```sprockets.stl.lib``` module. 8 | 9 | For instructions on how to write an STL file, see [STL.md](STL.md). 10 | 11 | ## 2. Documentation Generation 12 | Python documentation can be automatically generated from the project root by running: 13 | 14 | ``` 15 | cd $SPROCKETS_ROOT 16 | epydoc --exclude='.*pb2|.*proto.*' -o doc/html . 17 | ``` 18 | -------------------------------------------------------------------------------- /doc/html/crarr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/sprockets/6d551a413dc7daed594439f6ab2fab4e91c4473f/doc/html/crarr.png -------------------------------------------------------------------------------- /doc/html/frames.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | API Documentation 7 | 8 | 9 | 10 | 12 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | API Documentation 7 | 8 | 9 | 10 | 12 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/html/redirect.html: -------------------------------------------------------------------------------- 1 | Epydoc Redirect Page 2 | 3 | 4 | 5 | 6 | 7 | 8 | 18 | 19 |

Epydoc Auto-redirect page

20 | 21 |

When javascript is enabled, this page will redirect URLs of 22 | the form redirect.html#dotted.name to the 23 | documentation for the object with the given fully-qualified 24 | dotted name.

25 |

 

26 | 27 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /doc/html/sprockets-pysrc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sprockets 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 43 | 54 | 55 |
39 | 40 | Package sprockets 41 | 42 | 44 | 45 | 46 | 48 | 52 |
[hide private]
[frames] | no frames]
53 |
56 |

Source Code for Package sprockets

57 |
 58 | 1   
 59 | 2   
 64 | 
65 |
66 | 67 | 69 | 70 | 71 | 73 | 74 | 75 | 77 | 78 | 79 | 81 | 82 | 83 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 94 | 98 | 99 |
100 | 101 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /doc/html/sprockets.example-pysrc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sprockets.example 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 44 | 55 | 56 |
39 | 40 | Package sprockets :: 41 | Package example 42 | 43 | 45 | 46 | 47 | 49 | 53 |
[hide private]
[frames] | no frames]
54 |
57 |

Source Code for Package sprockets.example

58 |
 59 | 1   
 60 | 2   
 65 | 
66 |
67 | 68 | 70 | 71 | 72 | 74 | 75 | 76 | 78 | 79 | 80 | 82 | 83 | 84 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 95 | 99 | 100 |
101 | 102 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /doc/html/sprockets.example.proto-pysrc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sprockets.example.proto 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 45 | 56 | 57 |
39 | 40 | Package sprockets :: 41 | Package example :: 42 | Package proto 43 | 44 | 46 | 47 | 48 | 50 | 54 |
[hide private]
[frames] | no frames]
55 |
58 |

Source Code for Package sprockets.example.proto

59 |
 60 | 1   
 61 | 2   
 66 | 
67 |
68 | 69 | 71 | 72 | 73 | 75 | 76 | 77 | 79 | 80 | 81 | 83 | 84 | 85 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 96 | 100 | 101 |
102 | 103 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /doc/html/sprockets.example.run_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sprockets.example.run_test 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 45 | 56 | 57 |
39 | 40 | Package sprockets :: 41 | Package example :: 42 | Module run_test 43 | 44 | 46 | 47 | 48 | 50 | 54 |
[hide private]
[frames] | no frames]
55 |
58 | 59 |

Module run_test

source code

60 |
 61 | Test Driver wrapper for running for Cast STL conformance tests.
 62 | 
 63 | To run:
 64 |   $ python ./run_test.py <manifest file>
 65 | 
 66 | 
67 | 68 | 69 | 70 | 72 | 73 | 84 | 85 | 86 | 91 | 92 |
74 | 75 | 76 | 77 | 81 | 82 |
Variables[hide private]
83 |
87 |   88 | 89 | __package__ = 'sprockets.example' 90 |
93 | 94 | 96 | 97 | 98 | 100 | 101 | 102 | 104 | 105 | 106 | 108 | 109 | 110 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 121 | 125 | 126 |
127 | 128 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /doc/html/sprockets.stl-pysrc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sprockets.stl 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 44 | 55 | 56 |
39 | 40 | Package sprockets :: 41 | Package stl 42 | 43 | 45 | 46 | 47 | 49 | 53 |
[hide private]
[frames] | no frames]
54 |
57 |

Source Code for Package sprockets.stl

58 |
 59 | 1   
 60 | 2   
 65 | 
66 |
67 | 68 | 70 | 71 | 72 | 74 | 75 | 76 | 78 | 79 | 80 | 82 | 83 | 84 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 95 | 99 | 100 |
101 | 102 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /doc/html/test.sprockets-pysrc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | test.sprockets 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 44 | 55 | 56 |
39 | 40 | Package test :: 41 | Package sprockets 42 | 43 | 45 | 46 | 47 | 49 | 53 |
[hide private]
[frames] | no frames]
54 |
57 |

Source Code for Package test.sprockets

58 |
 59 | 1   
 60 | 2   
 65 | 
66 |
67 | 68 | 70 | 71 | 72 | 74 | 75 | 76 | 78 | 79 | 80 | 82 | 83 | 84 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 95 | 99 | 100 |
101 | 102 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /doc/html/test.sprockets.example-pysrc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | test.sprockets.example 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 45 | 56 | 57 |
39 | 40 | Package test :: 41 | Package sprockets :: 42 | Package example 43 | 44 | 46 | 47 | 48 | 50 | 54 |
[hide private]
[frames] | no frames]
55 |
58 |

Source Code for Package test.sprockets.example

59 |
 60 | 1   
 61 | 2   
 66 | 
67 |
68 | 69 | 71 | 72 | 73 | 75 | 76 | 77 | 79 | 80 | 81 | 83 | 84 | 85 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 96 | 100 | 101 |
102 | 103 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /doc/html/test.sprockets.example.proto-pysrc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | test.sprockets.example.proto 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 46 | 57 | 58 |
39 | 40 | Package test :: 41 | Package sprockets :: 42 | Package example :: 43 | Package proto 44 | 45 | 47 | 48 | 49 | 51 | 55 |
[hide private]
[frames] | no frames]
56 |
59 |

Source Code for Package test.sprockets.example.proto

60 |
 61 | 1   
 62 | 2   
 67 | 
68 |
69 | 70 | 72 | 73 | 74 | 76 | 77 | 78 | 80 | 81 | 82 | 84 | 85 | 86 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 97 | 101 | 102 |
103 | 104 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /doc/html/test.sprockets.stl-pysrc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | test.sprockets.stl 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 45 | 56 | 57 |
39 | 40 | Package test :: 41 | Package sprockets :: 42 | Package stl 43 | 44 | 46 | 47 | 48 | 50 | 54 |
[hide private]
[frames] | no frames]
55 |
58 |

Source Code for Package test.sprockets.stl

59 |
 60 | 1   
 61 | 2   
 66 | 
67 |
68 | 69 | 71 | 72 | 73 | 75 | 76 | 77 | 79 | 80 | 81 | 83 | 84 | 85 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 96 | 100 | 101 |
102 | 103 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sprockets 7 | 8 | 9 | 10 | 11 | 13 |

Module sprockets

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.example-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example 7 | 8 | 9 | 10 | 11 | 13 |

Module example

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.example.example_lib-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_lib 7 | 8 | 9 | 10 | 11 | 13 |

Module example_lib

14 |
15 |

Classes

16 | KeyValueEncoding

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.example.example_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_test 7 | 8 | 9 | 10 | 11 | 13 |

Module example_test

14 |
15 |

Classes

16 | KeyValueEncodingTestCase

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.example.noop-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | noop 7 | 8 | 9 | 10 | 11 | 13 |

Module noop

14 |
15 |

Classes

16 | LogEncodedParams
LogParams
NoOp
Sleep

Variables

21 | __package__

23 | [hide private] 25 | 26 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.example.proto-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | proto 7 | 8 | 9 | 10 | 11 | 13 |

Module proto

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.example.proto.example_pb2-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_pb2 7 | 8 | 9 | 10 | 11 | 13 |

Module example_pb2

14 |
15 |

Classes

16 | SimpleMsg

Variables

18 | DESCRIPTOR
20 | _SIMPLEMSG
22 | __package__

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.example.run_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | run_test 7 | 8 | 9 | 10 | 11 | 13 |

Module run_test

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | stl 7 | 8 | 9 | 10 | 11 | 13 |

Module stl

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.base-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | base 7 | 8 | 9 | 10 | 11 | 13 |

Module base

14 |
15 |

Classes

16 | Const
Expand
Field
Func
FuncGetField
FuncNoOp
FuncSet
FuncWithContext
LocalVar
NamedObject
Param
ParameterizedObject
QualifierValue
Role
TypedObject
Value

Functions

33 | GetCSV
IsString

Variables

36 | __package__

38 | [hide private] 40 | 41 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.base_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | base_test 7 | 8 | 9 | 10 | 11 | 13 |

Module base_test

14 |
15 |

Classes

16 | BaseTest

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.event-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | event 7 | 8 | 9 | 10 | 11 | 13 |

Module event

14 |
15 |

Classes

16 | Event
EventFromExternal
EventInTransition

Variables

20 | __package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.graph-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | graph 7 | 8 | 9 | 10 | 11 | 13 |

Module graph

14 |
15 |

Classes

16 | StateVertex
TransitionEdge

Functions

19 | BuildTransitionGraph
21 | _AddVertex
23 |

Variables

24 | __package__

26 | [hide private] 28 | 29 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.lib-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | lib 7 | 8 | 9 | 10 | 11 | 13 |

Module lib

14 |
15 |

Classes

16 | AnyOf
DifferentFrom
Encoding
Event
JsonEncoding
ProtobufBase64Encoding
ProtobufEncoding
Qualifier
RandomBool
RandomString
UniqueInt
UniqueString

Variables

29 | __package__

31 | [hide private] 33 | 34 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.message-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | message 7 | 8 | 9 | 10 | 11 | 13 |

Module message

14 |
15 |

Classes

16 | Message
MessageFromExternal
MessageValue

Variables

20 | __package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.message_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | message_test 7 | 8 | 9 | 10 | 11 | 13 |

Module message_test

14 |
15 |

Classes

16 | MessageTest

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.parser-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | parser 7 | 8 | 9 | 10 | 11 | 13 |

Module parser

14 |
15 |

Classes

16 | StlSyntaxError

Functions

18 | Parse
20 | _DebugLexer
22 |
23 | _DebugParser
25 |
26 | _GetLexer
28 |
29 | _GetParser
31 |
32 | _InitializeModuleDict
34 |
35 | _IsAlreadyDefined
37 | main

Variables

39 | __package__
literals
reserved
tokens

44 | [hide private] 46 | 47 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.parser_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | parser_test 7 | 8 | 9 | 10 | 11 | 13 |

Module parser_test

14 |
15 |

Classes

16 | StlParserTest

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.parser_test_proto_pb2-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | parser_test_proto_pb2 7 | 8 | 9 | 10 | 11 | 13 |

Module parser_test_proto_pb2

14 |
15 |

Classes

16 | SimpleMsg

Variables

18 | DESCRIPTOR
20 | _SIMPLEMSG
22 | __package__

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.qualifier-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | qualifier 7 | 8 | 9 | 10 | 11 | 13 |

Module qualifier

14 |
15 |

Classes

16 | Qualifier
QualifierFromExternal

Variables

19 | __package__

21 | [hide private] 23 | 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.state-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | state 7 | 8 | 9 | 10 | 11 | 13 |

Module state

14 |
15 |

Classes

16 | State
StateResolved
StateValue
StateValueInTransition
Transition

Variables

22 | __package__

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.state_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | state_test 7 | 8 | 9 | 10 | 11 | 13 |

Module state_test

14 |
15 |

Classes

16 | StateTest

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.stl.traverse-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | traverse 7 | 8 | 9 | 10 | 11 | 13 |

Module traverse

14 |
15 |

Classes

16 | Context

Functions

18 | MinEdgeCoverCircuit

Variables

20 | __package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/html/toc-sprockets.test_driver-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | test_driver 7 | 8 | 9 | 10 | 11 | 13 |

Module test_driver

14 |
15 |

Functions

16 | AddManifestRootToPath
FillInModuleRoles
GetRolesToTest
InitializeStates
LoadManifest
LoadModules
Main
NewModuleDict
ParseArgs
ParseStl
ResolveTransitions
TraverseGraph

Variables

29 | __package__

31 | [hide private] 33 | 34 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sprockets 7 | 8 | 9 | 10 | 11 | 13 |

Module sprockets

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.example-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example 7 | 8 | 9 | 10 | 11 | 13 |

Module example

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.example.example_lib-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_lib 7 | 8 | 9 | 10 | 11 | 13 |

Module example_lib

14 |
15 |

Classes

16 | KeyValueEncoding

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.example.example_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_test 7 | 8 | 9 | 10 | 11 | 13 |

Module example_test

14 |
15 |

Classes

16 | KeyValueEncodingTestCase

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.example.noop-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | noop 7 | 8 | 9 | 10 | 11 | 13 |

Module noop

14 |
15 |

Classes

16 | LogEncodedParams
LogParams
NoOp
Sleep

Variables

21 | __package__

23 | [hide private] 25 | 26 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.example.proto-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | proto 7 | 8 | 9 | 10 | 11 | 13 |

Module proto

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.example.proto.example_pb2-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | example_pb2 7 | 8 | 9 | 10 | 11 | 13 |

Module example_pb2

14 |
15 |

Classes

16 | SimpleMsg

Variables

18 | DESCRIPTOR
20 | _SIMPLEMSG
22 | __package__

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.example.run_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | run_test 7 | 8 | 9 | 10 | 11 | 13 |

Module run_test

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | stl 7 | 8 | 9 | 10 | 11 | 13 |

Module stl

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.base-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | base 7 | 8 | 9 | 10 | 11 | 13 |

Module base

14 |
15 |

Classes

16 | Const
Expand
Field
Func
FuncGetField
FuncNoOp
FuncSet
FuncWithContext
LocalVar
NamedObject
Param
ParameterizedObject
QualifierValue
Role
TypedObject
Value

Functions

33 | GetCSV
IsString

Variables

36 | __package__

38 | [hide private] 40 | 41 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.base_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | base_test 7 | 8 | 9 | 10 | 11 | 13 |

Module base_test

14 |
15 |

Classes

16 | BaseTest

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.event-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | event 7 | 8 | 9 | 10 | 11 | 13 |

Module event

14 |
15 |

Classes

16 | Event
EventFromExternal
EventInTransition

Variables

20 | __package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.graph-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | graph 7 | 8 | 9 | 10 | 11 | 13 |

Module graph

14 |
15 |

Classes

16 | StateVertex
TransitionEdge

Functions

19 | BuildTransitionGraph
21 | _AddVertex
23 |

Variables

24 | __package__

26 | [hide private] 28 | 29 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.lib-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | lib 7 | 8 | 9 | 10 | 11 | 13 |

Module lib

14 |
15 |

Classes

16 | AnyOf
DifferentFrom
Encoding
Event
JsonEncoding
ProtobufBase64Encoding
ProtobufEncoding
Qualifier
RandomBool
RandomString
UniqueInt
UniqueString

Variables

29 | __package__

31 | [hide private] 33 | 34 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.message-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | message 7 | 8 | 9 | 10 | 11 | 13 |

Module message

14 |
15 |

Classes

16 | Message
MessageFromExternal
MessageValue

Variables

20 | __package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.message_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | message_test 7 | 8 | 9 | 10 | 11 | 13 |

Module message_test

14 |
15 |

Classes

16 | MessageTest

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.parser-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | parser 7 | 8 | 9 | 10 | 11 | 13 |

Module parser

14 |
15 |

Classes

16 | StlSyntaxError

Functions

18 | Parse
20 | _DebugLexer
22 |
23 | _DebugParser
25 |
26 | _GetLexer
28 |
29 | _GetParser
31 |
32 | _InitializeModuleDict
34 |
35 | _IsAlreadyDefined
37 | main

Variables

39 | __package__
literals
reserved
tokens

44 | [hide private] 46 | 47 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.parser_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | parser_test 7 | 8 | 9 | 10 | 11 | 13 |

Module parser_test

14 |
15 |

Classes

16 | StlParserTest

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.parser_test_proto_pb2-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | parser_test_proto_pb2 7 | 8 | 9 | 10 | 11 | 13 |

Module parser_test_proto_pb2

14 |
15 |

Classes

16 | SimpleMsg

Variables

18 | DESCRIPTOR
20 | _SIMPLEMSG
22 | __package__

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.qualifier-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | qualifier 7 | 8 | 9 | 10 | 11 | 13 |

Module qualifier

14 |
15 |

Classes

16 | Qualifier
QualifierFromExternal

Variables

19 | __package__

21 | [hide private] 23 | 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.state-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | state 7 | 8 | 9 | 10 | 11 | 13 |

Module state

14 |
15 |

Classes

16 | State
StateResolved
StateValue
StateValueInTransition
Transition

Variables

22 | __package__

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.state_test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | state_test 7 | 8 | 9 | 10 | 11 | 13 |

Module state_test

14 |
15 |

Classes

16 | StateTest

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.stl.traverse-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | traverse 7 | 8 | 9 | 10 | 11 | 13 |

Module traverse

14 |
15 |

Classes

16 | Context

Functions

18 | MinEdgeCoverCircuit

Variables

20 | __package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/html/toc-test.sprockets.test_driver-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | test_driver 7 | 8 | 9 | 10 | 11 | 13 |

Module test_driver

14 |
15 |

Functions

16 | AddManifestRootToPath
FillInModuleRoles
GetRolesToTest
InitializeStates
LoadManifest
LoadModules
Main
NewModuleDict
ParseArgs
ParseStl
ResolveTransitions
TraverseGraph

Variables

29 | __package__

31 | [hide private] 33 | 34 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /doc/html/toc.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Table of Contents 7 | 8 | 9 | 10 | 11 | 13 |

Table of Contents

14 |
15 | Everything 16 |
17 |

Modules

18 | sprockets
sprockets.example
sprockets.example.example_lib
sprockets.example.example_test
sprockets.example.noop
sprockets.example.run_test
sprockets.stl
sprockets.stl.base
sprockets.stl.base_test
sprockets.stl.event
sprockets.stl.graph
sprockets.stl.lib
sprockets.stl.message
sprockets.stl.message_test
sprockets.stl.parser
sprockets.stl.parser_test
sprockets.stl.qualifier
sprockets.stl.state
sprockets.stl.state_test
sprockets.stl.traverse
sprockets.test_driver

40 | [hide private] 42 | 43 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /editor_support/sublime-text/README.md: -------------------------------------------------------------------------------- 1 | # Sublime Text Support 2 | 3 | This folder contains various tools and configs for supporting STL and Sprockets 4 | in Sublime Text. 5 | 6 | ## Syntax Highlighting 7 | 8 | 1. Copy the `stl.YAML-tmLanguage` file to: 9 | `~/.config/sublime-text-2/Packages/User/stl.YAML-tmLanguage` 10 | This file defines how to highlight stl files in Sublime Text. 11 | 12 | 2. Install the `PackageDev` package: https://github.com/SublimeText/PackageDev 13 | Follow the 'Getting Started' instructions in the README. 14 | 15 | 3. In Sublime, open the `stl.YAML-tmLanguage` file. 16 | 17 | 4. Open the command palette (Ctrl+Shift+P) and run: 18 | `PackageDev: Convert (YAML, JSON, PList) to...` 19 | This will convert the YAML syntax file into a Sublime Test property list, 20 | which can then be applied to your STL files. 21 | 22 | 5. Open your STL file and open the command palette, selecting: 23 | `Set Syntax: State Transition Language`. This will apply the STL syntax 24 | highlighting to your file, if it is not already applied. 25 | -------------------------------------------------------------------------------- /editor_support/sublime-text/stl.YAML-tmLanguage: -------------------------------------------------------------------------------- 1 | # [PackageDev] target_format: plist, ext: tmLanguage 2 | # Copyright 2016 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | --- 17 | name: State Transition Language 18 | scopeName: source.stl 19 | fileTypes: [stl] 20 | uuid: 507fdb50-d543-486f-99ec-211866733818 21 | 22 | patterns: 23 | - name: string.stl 24 | match: \".*\" 25 | - begin: (role)\s*([a-zA-Z0-9]+)\s*\{ 26 | beginCaptures: 27 | '1': {name: keyword.type.stl} 28 | '2': {name: entity.name.function.stl} 29 | end: \} 30 | patterns: 31 | - include: $self 32 | - begin: (state)\s*([a-zA-Z0-9]+)\s*\{ 33 | beginCaptures: 34 | '1': {name: keyword.type.stl} 35 | '2': {name: entity.name.function.stl} 36 | end: \} 37 | patterns: 38 | - include: $self 39 | - begin: (message)(\[\])?\s*([a-zA-Z0-9]+)\s*\{ 40 | beginCaptures: 41 | '1': {name: keyword.type.stl} 42 | '3': {name: entity.name.function.stl} 43 | end: \} 44 | patterns: 45 | - include: $self 46 | - begin: ([a-zA-Z0-9]+)\s*\( 47 | beginCaptures: 48 | '1': {name: entity.name.function.stl} 49 | end: \) 50 | patterns: 51 | - include: $self 52 | - begin: '([a-zA-Z0-9]+)\s*\{' 53 | beginCaptures: 54 | '1': {name: entity.name.function.stl} 55 | end: \} 56 | patterns: 57 | - include: $self 58 | - begin: '([a-zA-Z0-9]+)\s*\[' 59 | beginCaptures: 60 | '1': {name: entity.name.function.stl} 61 | end: \] 62 | patterns: 63 | - include: $self 64 | - name: keyword.stl 65 | match: const 66 | - name: keyword.transition.stl 67 | match: pre_states|post_states|events 68 | - name: keyword.type.stl 69 | match: role|qualifier|event|transition 70 | - name: storage.type.stl 71 | match: int|string|double|bool 72 | - name: keyword.operator.stl 73 | match: required|repeated|optional 74 | - name: keyword.other.stl 75 | match: encode|external 76 | - name: constant.numeric.stl 77 | match: \d* 78 | - name: comment.stl 79 | match: //.*$ 80 | ... 81 | -------------------------------------------------------------------------------- /editor_support/vim/README.md: -------------------------------------------------------------------------------- 1 | # Vim Support 2 | 3 | This folder contains various tools and configs for supporting STL and Sprockets 4 | in Vim. 5 | 6 | ## Syntax Highlighting 7 | 8 | 1. Copy the `syntax/stl.vim` file to `~/.vim/syntax/stl.vim` 9 | This file defines how to highlight stl files. 10 | 11 | 2. Copy the `ftdetect/stl.vim` file to `~/.vim/ftdetect/stl.vim` 12 | This file tells vim to highlight *.stl files with the proper style. 13 | -------------------------------------------------------------------------------- /editor_support/vim/ftdetect/stl.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2016 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | " Filetype detection for Sprockets STL files. 16 | au BufRead,BufNewFile *.stl setfiletype stl 17 | -------------------------------------------------------------------------------- /editor_support/vim/syntax/stl.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2016 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | " Vim syntax file 16 | " Language: Sprockets STL 17 | " Maintainer: mbjorge@google.com 18 | 19 | if exists("b:current_syntax") 20 | finish 21 | endif 22 | 23 | "-------------- 24 | " STL comments 25 | "-------------- 26 | syn keyword stlTodo contained TODO 27 | syn match stlComment '//.*$' contains=stlTodo 28 | 29 | "-------------------- 30 | " STL reserved words 31 | "-------------------- 32 | syn keyword stlReservedWordsTypes const bool int string 33 | syn keyword stlReservedWords encode error_states event events message 34 | syn keyword stlReservedWords module optional post_states pre_states qualifier 35 | syn keyword stlReservedWords repeated required role state transition 36 | 37 | "--------------- 38 | " STL externals 39 | "--------------- 40 | syn region stlExternalString start='"'hs=s+1 end='"'he=e-1 contained 41 | syn keyword stlReservedWords external nextgroup=stlExternalString skipwhite 42 | 43 | "------------- 44 | " STL symbols 45 | "------------- 46 | syn match stlArrow '->' 47 | 48 | "--------------------- 49 | " STL constant values 50 | "--------------------- 51 | syn keyword stlBool true false 52 | 53 | syn match stlInt '[-]\d+' 54 | syn match stlInt '\d+' 55 | 56 | syn region stlString start='"' skip='\\"' end='"' 57 | 58 | 59 | "------------------------ 60 | " Set the current syntax 61 | "------------------------ 62 | let b:current_syntax = 'stl' 63 | 64 | "------------------------ 65 | " STL highlighting rules 66 | "------------------------ 67 | hi def link stlTodo Todo 68 | hi def link stlComment Comment 69 | hi def link stlReservedWords Keyword 70 | hi def link stlReservedWordsTypes Type 71 | hi def link stlArrow Operator 72 | hi def link stlBoolean Boolean 73 | hi def link stlInt Number 74 | hi def link stlString String 75 | hi def link stlExternalString Underlined 76 | -------------------------------------------------------------------------------- /end_to_end_test_data/did_you_mean_state_value.stl: -------------------------------------------------------------------------------- 1 | // Test the "Did you mean..." suggestions for a typo in a state value. 2 | 3 | module example; 4 | 5 | const string kHelloWorld; 6 | 7 | role rSender { 8 | string ipAddress; 9 | } 10 | 11 | role rReceiver { 12 | string ipAddress; 13 | } 14 | 15 | state sTlsState(int tlsId) { 16 | kNotConnected, 17 | kConnected, 18 | } 19 | 20 | event NoOp(int tlsId) = external "noop.NoOp"; 21 | 22 | transition tConnectTls(int tlsId) { 23 | pre_states = [ sTlsState(tlsId).kNotConnected ] 24 | events { 25 | rSender -> NoOp(tlsId) -> rReceiver; 26 | } 27 | post_states = [ sTlsState(tlsId).kConnected ] 28 | } 29 | 30 | transition tDisconnectTls(int tlsId) { 31 | pre_states = [ sTlsState(tlsId).kConnected ] 32 | events { 33 | rSender -> NoOp(tlsId) -> rReceiver; 34 | } 35 | // !!! Typo in the state value !!! 36 | post_states = [ sTlsState(tlsId).knotconnected ] 37 | } 38 | 39 | transition tConnectTlsActual = tConnectTls(1); 40 | transition tDisconnectTlsActual = tDisconnectTls(1); 41 | -------------------------------------------------------------------------------- /end_to_end_test_data/did_you_mean_state_value.test: -------------------------------------------------------------------------------- 1 | { 2 | 'stl_files': [ 3 | 'did_you_mean_state_value.stl', 4 | ], 5 | 6 | 'roles': [ # Role information 7 | { 'role': 'example::rReceiver', 8 | 'ipAddress': '0.0.0.0', 9 | }, 10 | ], 11 | 12 | 'constants': { 13 | 'example::kHelloWorld': 'Hello, world!', 14 | }, 15 | 16 | 'test': ['example::rReceiver'], 17 | } 18 | -------------------------------------------------------------------------------- /end_to_end_test_data/did_you_mean_transition.stl: -------------------------------------------------------------------------------- 1 | // Test the "Did you mean..." suggestions for a typo in a transition name. 2 | 3 | module example; 4 | 5 | const string kHelloWorld; 6 | 7 | role rSender { 8 | string ipAddress; 9 | } 10 | 11 | role rReceiver { 12 | string ipAddress; 13 | } 14 | 15 | state sTlsState(int tlsId) { 16 | kNotConnected, 17 | kConnected, 18 | } 19 | 20 | event NoOp(int tlsId) = external "noop.NoOp"; 21 | 22 | transition tConnectTls(int tlsId) { 23 | pre_states = [ sTlsState(tlsId).kNotConnected ] 24 | events { 25 | rSender -> NoOp(tlsId) -> rReceiver; 26 | } 27 | post_states = [ sTlsState(tlsId).kConnected ] 28 | } 29 | 30 | transition tDisconnectTls(int tlsId) { 31 | pre_states = [ sTlsState(tlsId).kConnected ] 32 | events { 33 | rSender -> NoOp(tlsId) -> rReceiver; 34 | } 35 | post_states = [ sTlsState(tlsId).kNotConnected ] 36 | } 37 | 38 | // !!! Typo in the transistion name !!! 39 | transition tConnectTlsActual = tCnnctTls(1); 40 | transition tDisconnectTlsActual = tDisconnectTls(1); 41 | -------------------------------------------------------------------------------- /end_to_end_test_data/did_you_mean_transition.test: -------------------------------------------------------------------------------- 1 | { 2 | 'stl_files': [ 3 | 'did_you_mean_transition.stl', 4 | ], 5 | 6 | 'roles': [ # Role information 7 | { 'role': 'example::rReceiver', 8 | 'ipAddress': '0.0.0.0', 9 | }, 10 | ], 11 | 12 | 'constants': { 13 | 'example::kHelloWorld': 'Hello, world!', 14 | }, 15 | 16 | 'test': ['example::rReceiver'], 17 | } 18 | -------------------------------------------------------------------------------- /end_to_end_test_data/noop.py: -------------------------------------------------------------------------------- 1 | import stl.lib 2 | 3 | 4 | class NoOp(stl.lib.Event): 5 | 6 | def Fire(self, *args): 7 | return True 8 | 9 | def Wait(self, *args): 10 | return True 11 | -------------------------------------------------------------------------------- /end_to_end_test_data/simple_example.stl: -------------------------------------------------------------------------------- 1 | // This is a very basic module that compiles and runs successfully. 2 | 3 | module example; 4 | 5 | const string kHelloWorld; 6 | 7 | role rSender { 8 | string ipAddress; 9 | } 10 | 11 | role rReceiver { 12 | string ipAddress; 13 | } 14 | 15 | state sTlsState(int tlsId) { 16 | kNotConnected, 17 | kConnected, 18 | } 19 | 20 | event Sleep(int tlsId) = external "noop.NoOp"; 21 | 22 | transition tConnectTls(int tlsId) { 23 | pre_states = [ sTlsState(tlsId).kNotConnected ] 24 | events { 25 | rSender -> Sleep(tlsId) -> rReceiver; 26 | } 27 | post_states = [ sTlsState(tlsId).kConnected ] 28 | } 29 | 30 | transition tDisconnectTls(int tlsId) { 31 | pre_states = [ sTlsState(tlsId).kConnected ] 32 | events { 33 | rSender -> Sleep(tlsId) -> rReceiver; 34 | } 35 | post_states = [ sTlsState(tlsId).kNotConnected ] 36 | } 37 | 38 | transition tConnectTlsActual = tConnectTls(1); 39 | transition tDisconnectTlsActual = tDisconnectTls(1); 40 | -------------------------------------------------------------------------------- /end_to_end_test_data/simple_example.test: -------------------------------------------------------------------------------- 1 | { 2 | 'stl_files': [ 3 | 'simple_example.stl', 4 | ], 5 | 6 | 'roles': [ # Role information 7 | { 'role': 'example::rReceiver', 8 | 'ipAddress': '0.0.0.0', 9 | }, 10 | ], 11 | 12 | 'constants': { 13 | 'example::kHelloWorld': 'Hello, world!', 14 | }, 15 | 16 | 'test': ['example::rReceiver'], 17 | } 18 | -------------------------------------------------------------------------------- /example/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/sprockets/6d551a413dc7daed594439f6ab2fab4e91c4473f/example/__init__.py -------------------------------------------------------------------------------- /example/example.stl: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | module example; 16 | 17 | transition tConnectTlsActual = tConnectTls(1); 18 | transition tDisconnectTlsActual = tDisconnectTls(1); 19 | transition tRequestResponseActual = tRequestResponse(1); 20 | transition tRequestResponseCustomActual = tRequestResponseCustom(1); 21 | -------------------------------------------------------------------------------- /example/example.test: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This test can be run from this directory with: 16 | # PYTHONPATH=$PYTHONPATH:$PWD/.. python run_test.py example.test 17 | # -a ip=\"127.0.0.1\" hello_world='"Hello, world!"' 18 | { 19 | 'stl_files': [ 20 | 'example_base.stl', 21 | 'example.stl', 22 | ], 23 | 24 | 'roles': [ # Role information 25 | { 'role': 'example::rReceiver', 26 | 'ipAddress': $ip, # Must pass --manifest-args 'ip="0.0.0.0"' 27 | 'transportId': 'receiver-0', 28 | }, 29 | ], 30 | 31 | 'constants': { 32 | 'example::kHelloWorld': $hello_world, # Must pass --manifest-args \ 33 | # 'hello_world="Hello, world!"' 34 | }, 35 | 36 | 'test': ['example::rReceiver'], 37 | } 38 | -------------------------------------------------------------------------------- /example/example_base.stl: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | module example; 16 | 17 | // Constants 18 | // 19 | const string kHelloWorld; 20 | 21 | // Roles 22 | // 23 | role rSender { 24 | string ipAddress; 25 | string transportId; 26 | } 27 | 28 | role rReceiver { 29 | string ipAddress; 30 | string transportId; 31 | } 32 | 33 | // States 34 | // 35 | state sTlsState(int tlsId) { 36 | kNotConnected, 37 | kConnected, 38 | } 39 | 40 | // Messages 41 | // 42 | message mSimpleMessage { 43 | encode "stl.lib.JsonEncoding"; 44 | required string words; 45 | } 46 | 47 | message[] mMessageArray { 48 | encode "stl.lib.JsonEncoding"; 49 | required int i; 50 | } 51 | 52 | message mProtoMessage { 53 | encode "stl.lib.ProtobufEncoding"; 54 | external "proto.example_pb2.SimpleMsg"; 55 | } 56 | 57 | message mMessageWithData { 58 | encode "stl.lib.JsonEncoding"; 59 | 60 | required int request_id; 61 | required string data; 62 | optional string optional_data; 63 | repeated string optional_repeated_data; 64 | optional mNestedMessage optional_nested_data; 65 | 66 | message mNestedMessage { 67 | required string data; 68 | } 69 | } 70 | 71 | message mCustomEncodeMessage { 72 | encode "example_lib.KeyValueEncoding"; 73 | required int request_id : "ord" = 0, "key" = "ri"; 74 | required string data : "ord" = 1, "key" = "da"; 75 | } 76 | 77 | // Qualifiers 78 | // 79 | qualifier int UniqueInt() = external "stl.lib.UniqueInt"; 80 | 81 | // Events 82 | // 83 | event Sleep(int tlsId) = external "noop.Sleep"; 84 | event LogParams(mSimpleMessage msg) = external "noop.LogParams"; 85 | event LogEncodedParams(mMessagearray msg) = external "noop.LogEncodedParams"; 86 | 87 | event SendRequest(int& requestId, string data) = 88 | LogEncodedParams(mMessageWithData { 89 | request_id = UniqueInt() -> requestId; 90 | data = data; 91 | }); 92 | 93 | event SendResponse(int requestId, string data) = 94 | LogEncodedParams(mMessageWithData { 95 | request_id = requestId; 96 | data = data; 97 | }); 98 | 99 | event SendRequestCustom(int& requestId, string data) = 100 | LogEncodedParams(mCustomEncodeMessage { 101 | request_id = UniqueInt() -> requestId; 102 | data = data; 103 | }); 104 | 105 | event SendResponseCustom(int requestId, string data) = 106 | LogEncodedParams(mCustomEncodeMessage { 107 | request_id = requestId; 108 | data = data; 109 | }); 110 | 111 | // Transitions 112 | // 113 | transition tConnectTls(int tlsId) { 114 | pre_states = [ sTlsState(tlsId).kNotConnected ] 115 | events { 116 | rSender -> Sleep(tlsId) -> rReceiver; 117 | } 118 | post_states = [ sTlsState(tlsId).kConnected ] 119 | } 120 | 121 | transition tDisconnectTls(int tlsId) { 122 | pre_states = [ sTlsState(tlsId).kConnected ] 123 | events { 124 | rSender -> LogParams(mSimpleMessage { words = kHelloWorld; }) -> rReceiver; 125 | rSender -> LogEncodedParams(mMessageArray [{ i = 600; }, {i = 30;}]) -> rReceiver; 126 | rSender -> LogEncodedParams(mProtoMessage { 127 | foo = mMessageArray [{ i = 13; }, { i = 14;}]; 128 | fizz = 12345; 129 | buzz = [true, true, false]; 130 | }) -> rReceiver; 131 | } 132 | post_states = [ sTlsState(tlsId).kNotConnected ] 133 | } 134 | 135 | transition tRequestResponse(int tlsId) { 136 | int requestId; 137 | pre_states = [ sTlsState(tlsId).kConnected ] 138 | events { 139 | rSender -> SendRequest(&requestId, "REQUEST") -> rReceiver; 140 | rReceiver -> SendResponse(requestId, "RESPONSE") -> rSender; 141 | } 142 | post_states = [] 143 | } 144 | 145 | transition tRequestResponseCustom(int tlsId) { 146 | int requestId; 147 | pre_states = [ sTlsState(tlsId).kConnected ] 148 | events { 149 | rSender -> SendRequestCustom(&requestId, "REQUEST") -> rReceiver; 150 | rReceiver -> SendResponseCustom(requestId, "RESPONSE") -> rSender; 151 | } 152 | post_states = [] 153 | } 154 | -------------------------------------------------------------------------------- /example/example_lib.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Encodes a message into a concatenated sequence of key/value pairs.""" 16 | 17 | import stl.lib 18 | 19 | 20 | class KeyValueEncoding(stl.lib.Encoding): 21 | """Key/Value pair encoding. 22 | 23 | Each message field should have two extra properties: 24 | ord: The ordering of the keys. 25 | key: The key to use in the encoded message. 26 | 27 | The format of the encoded message is: 28 | '=,=,...' 29 | """ 30 | 31 | def SerializeToString(self, values, message_type): 32 | kv_pairs = [None] * len(message_type.fields) 33 | for field in message_type.fields: 34 | order = field.encoding_props['ord'] 35 | key = field.encoding_props['key'] 36 | if field.name in values: 37 | val = values[field.name] 38 | if field.type_ == 'bool': 39 | kv_pairs[order] = '%s=%s' % (key, val) 40 | if field.type_ == 'int': 41 | kv_pairs[order] = '%s=%d' % (key, val) 42 | if field.type_ == 'string': 43 | kv_pairs[order] = '%s=%s' % (key, val) 44 | delim = ',' 45 | return delim.join(kv_pairs) 46 | 47 | def ParseFromString(self, encoded, message_type): 48 | values = {} 49 | field_dict = { 50 | field.encoding_props['key']: field 51 | for field in message_type.fields 52 | } 53 | for pair in encoded.split(','): 54 | key, value = pair.split('=') 55 | field = field_dict[key] 56 | if field.type_ == 'bool': 57 | values[field.name] = value == 'True' 58 | if field.type_ == 'int': 59 | values[field.name] = int(value) 60 | if field.type_ == 'string': 61 | values[field.name] = value 62 | return values 63 | -------------------------------------------------------------------------------- /example/example_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2016 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | """Tests for example user-defined encoding scheme.""" 16 | 17 | import unittest 18 | 19 | import stl.base 20 | import stl.message 21 | 22 | 23 | class KeyValueEncodingTestCase(unittest.TestCase): 24 | """Test KeyValueEncoding serialization and parsing.""" 25 | 26 | def testSerializeToString(self): 27 | message = stl.message.Message( 28 | 'mMessage', 'example_lib.KeyValueEncoding', False) 29 | field1 = stl.base.Field('request_id', 'int') 30 | field1.encoding_props['ord'] = 0 31 | field1.encoding_props['key'] = 'ri' 32 | field2 = stl.base.Field('data', 'string') 33 | field2.encoding_props['ord'] = 1 34 | field2.encoding_props['key'] = 'da' 35 | field3 = stl.base.Field('broadcast', 'bool') 36 | field3.encoding_props['ord'] = 2 37 | field3.encoding_props['key'] = 'br' 38 | message.fields = [field1, field2, field3] 39 | 40 | values = {'request_id': 10, 'data': 'dummy_data', 'broadcast': True} 41 | serialized = message.encoding.SerializeToString(values, message) 42 | self.assertEquals('ri=10,da=dummy_data,br=True', serialized) 43 | 44 | def testParseFromString(self): 45 | message = stl.message.Message( 46 | 'mMessage', 'example_lib.KeyValueEncoding', False) 47 | field1 = stl.base.Field('request_id', 'int') 48 | field1.encoding_props['ord'] = 0 49 | field1.encoding_props['key'] = 'ri' 50 | field2 = stl.base.Field('data', 'string') 51 | field2.encoding_props['ord'] = 1 52 | field2.encoding_props['key'] = 'da' 53 | field3 = stl.base.Field('broadcast', 'bool') 54 | field3.encoding_props['ord'] = 2 55 | field3.encoding_props['key'] = 'br' 56 | message.fields = [field1, field2, field3] 57 | 58 | encoded = 'ri=10,da=dummy_data,br=True' 59 | decoded = message.encoding.ParseFromString(encoded, message) 60 | expected = {'request_id': 10, 'data': 'dummy_data', 'broadcast': True} 61 | self.assertEquals(expected, decoded) 62 | 63 | 64 | if __name__ == '__main__': 65 | unittest.main() 66 | -------------------------------------------------------------------------------- /example/noop.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Dummy external event functions. 16 | 17 | It defines a set of dummy functions helpful for testing/debugging. 18 | """ 19 | 20 | import logging 21 | import time 22 | 23 | import stl.lib 24 | 25 | 26 | class NoOp(stl.lib.Event): 27 | 28 | def Fire(self, context): 29 | """Do nothing, always return success.""" 30 | del context # Unused. 31 | return True 32 | 33 | def Wait(self, context): 34 | """Do nothing, always return success.""" 35 | del context # Unused. 36 | return True 37 | 38 | 39 | class Sleep(stl.lib.Event): 40 | 41 | def Fire(self, context, sleep_secs): 42 | """A dummy method that just sleeps for |sleep_secs|.""" 43 | del context # Unused. 44 | time.sleep(sleep_secs) 45 | return True 46 | 47 | def Wait(self, context, sleep_secs): 48 | """A dummy method that just sleeps for |sleep_secs|.""" 49 | del context # Unused. 50 | time.sleep(sleep_secs) 51 | return True 52 | 53 | 54 | class LogParams(stl.lib.Event): 55 | 56 | def Fire(self, *args): 57 | """A dummy method that dumps all args to logging.info.""" 58 | logging.info('LogParams: %s', [str(arg) for arg in args]) 59 | return True 60 | 61 | def Wait(self, *args): 62 | """A dummy method that dumps all args to logging.info.""" 63 | logging.info('LogParams: %s', [str(arg) for arg in args]) 64 | return True 65 | 66 | 67 | class LogEncodedParams(stl.lib.Event): 68 | 69 | def Fire(self, context, params): 70 | return self._Log(context, params) 71 | 72 | def Wait(self, context, params): 73 | return self._Log(context, params) 74 | 75 | def _Log(self, context, params): 76 | """A dummy method that encodes |params| and dumps that to logging.info.""" 77 | del context # Unused. 78 | if not isinstance(params, list): 79 | params = [params] 80 | logging.info('LogEncodedParams: %s', [param.Encode() for param in params]) 81 | return True 82 | -------------------------------------------------------------------------------- /example/proto/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/sprockets/6d551a413dc7daed594439f6ab2fab4e91c4473f/example/proto/__init__.py -------------------------------------------------------------------------------- /example/proto/example.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // A proto file for example.stl. 16 | 17 | syntax = "proto2"; 18 | 19 | option optimize_for = LITE_RUNTIME; 20 | 21 | package bar; 22 | 23 | message SimpleMsg { 24 | required string foo = 1; 25 | optional int32 fizz = 2; 26 | repeated bool buzz = 3; 27 | } 28 | -------------------------------------------------------------------------------- /example/proto/example_pb2.py: -------------------------------------------------------------------------------- 1 | # Generated by the protocol buffer compiler. DO NOT EDIT! 2 | # source: example.proto 3 | 4 | import sys 5 | _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import message as _message 8 | from google.protobuf import reflection as _reflection 9 | from google.protobuf import symbol_database as _symbol_database 10 | from google.protobuf import descriptor_pb2 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | 17 | 18 | DESCRIPTOR = _descriptor.FileDescriptor( 19 | name='example.proto', 20 | package='bar', 21 | syntax='proto2', 22 | serialized_pb=_b('\n\rexample.proto\x12\x03\x62\x61r\"4\n\tSimpleMsg\x12\x0b\n\x03\x66oo\x18\x01 \x02(\t\x12\x0c\n\x04\x66izz\x18\x02 \x01(\x05\x12\x0c\n\x04\x62uzz\x18\x03 \x03(\x08\x42\x02H\x03') 23 | ) 24 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 25 | 26 | 27 | 28 | 29 | _SIMPLEMSG = _descriptor.Descriptor( 30 | name='SimpleMsg', 31 | full_name='bar.SimpleMsg', 32 | filename=None, 33 | file=DESCRIPTOR, 34 | containing_type=None, 35 | fields=[ 36 | _descriptor.FieldDescriptor( 37 | name='foo', full_name='bar.SimpleMsg.foo', index=0, 38 | number=1, type=9, cpp_type=9, label=2, 39 | has_default_value=False, default_value=_b("").decode('utf-8'), 40 | message_type=None, enum_type=None, containing_type=None, 41 | is_extension=False, extension_scope=None, 42 | options=None), 43 | _descriptor.FieldDescriptor( 44 | name='fizz', full_name='bar.SimpleMsg.fizz', index=1, 45 | number=2, type=5, cpp_type=1, label=1, 46 | has_default_value=False, default_value=0, 47 | message_type=None, enum_type=None, containing_type=None, 48 | is_extension=False, extension_scope=None, 49 | options=None), 50 | _descriptor.FieldDescriptor( 51 | name='buzz', full_name='bar.SimpleMsg.buzz', index=2, 52 | number=3, type=8, cpp_type=7, label=3, 53 | has_default_value=False, default_value=[], 54 | message_type=None, enum_type=None, containing_type=None, 55 | is_extension=False, extension_scope=None, 56 | options=None), 57 | ], 58 | extensions=[ 59 | ], 60 | nested_types=[], 61 | enum_types=[ 62 | ], 63 | options=None, 64 | is_extendable=False, 65 | syntax='proto2', 66 | extension_ranges=[], 67 | oneofs=[ 68 | ], 69 | serialized_start=22, 70 | serialized_end=74, 71 | ) 72 | 73 | DESCRIPTOR.message_types_by_name['SimpleMsg'] = _SIMPLEMSG 74 | 75 | SimpleMsg = _reflection.GeneratedProtocolMessageType('SimpleMsg', (_message.Message,), dict( 76 | DESCRIPTOR = _SIMPLEMSG, 77 | __module__ = 'example_pb2' 78 | # @@protoc_insertion_point(class_scope:bar.SimpleMsg) 79 | )) 80 | _sym_db.RegisterMessage(SimpleMsg) 81 | 82 | 83 | DESCRIPTOR.has_options = True 84 | DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('H\003')) 85 | # @@protoc_insertion_point(module_scope) 86 | -------------------------------------------------------------------------------- /example/test_runner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2016 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """Test Driver wrapper for running for Cast STL conformance tests. 17 | 18 | To run: 19 | $ python ./run_test.py 20 | """ 21 | 22 | import sys 23 | 24 | import test_driver 25 | 26 | 27 | if __name__ == '__main__': 28 | sys.exit(0 if test_driver.Main() else 1) 29 | -------------------------------------------------------------------------------- /gui/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2017 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """Exports symbols for gui module.""" 17 | 18 | from gui.gui_server import GuiObserver 19 | from gui.gui_server import GuiServer 20 | -------------------------------------------------------------------------------- /gui/gui_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2017 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """GUI server running a web server internally. 17 | 18 | A simple example to run GUI server: 19 | 20 | import gui 21 | 22 | class MyObserver(gui.GuiObserver): 23 | def OnGetStatus(self, gui_server, client_id): 24 | status_data = 25 | gui_server.Send(client_id, status_data) 26 | 27 | def OnStart(self, gui_server, client_id): 28 | 29 | gui_server.Broadcast(client, 'Started') 30 | gui_server.Send(client, 'Success') 31 | 32 | def OnStop(self, gui_server, client_id): 33 | 34 | gui_server.Broadcast(client, 'Stopped') 35 | gui_server.Send(client, 'Success') 36 | 37 | observer = MyObserver() 38 | gui_server = gui.GuiServer(8080, observer) 39 | gui_server.Start() # current implementation doesn't return from here 40 | # until the server stops. 41 | gui_server.Stop() 42 | """ 43 | 44 | import abc 45 | import logging 46 | import os 47 | 48 | import gui.websocket_server 49 | 50 | 51 | class GuiObserver(object): 52 | """Observer interface of GUI server.""" 53 | 54 | __metaclass__ = abc.ABCMeta 55 | 56 | @abc.abstractmethod 57 | def OnGetStatus(self, gui_server, client_id): 58 | """Called on GET_STATUS requests from GUI clients.""" 59 | 60 | @abc.abstractmethod 61 | def OnStart(self, gui_server, client_id): 62 | """Called on START requests from GUI clients.""" 63 | 64 | @abc.abstractmethod 65 | def OnStop(self, gui_server, client_id): 66 | """Called on STOP requests from GUI clients.""" 67 | 68 | 69 | class GuiServer(object): 70 | """GUI server running a web server internally.""" 71 | 72 | # Absolute URL path of Websocket. 73 | _WEBSOCKET_URL = '/sprockets/ws' 74 | 75 | # Absolute directory URL path of html resources. 76 | _HTML_DIR_URL = '/sprockets/gui' 77 | 78 | # Absolute URL path of GUI main.html. 79 | _MAIN_HTML_URL = _HTML_DIR_URL + '/main.html' 80 | 81 | # Absolute directory file path of html resources. 82 | _HTML_DIR_PATH = os.path.dirname(__file__) + '/html' 83 | 84 | def __init__(self, port, observer): 85 | """Instantiates a GUI server. 86 | 87 | Args: 88 | port: tcp/ssl port for internal web server. 89 | observer: GuiObserver called on requests. 90 | """ 91 | self._web_server = gui.websocket_server.WebSocketServer() 92 | self._port = port 93 | self._observer = observer 94 | self._clients = set() 95 | 96 | def Start(self): 97 | """Starts accepting requests from GUI clients.""" 98 | self._web_server.Start(self._port, self._OnData, self._OnError, 99 | self._WEBSOCKET_URL, self._MAIN_HTML_URL, 100 | self._HTML_DIR_URL, self._HTML_DIR_PATH) 101 | 102 | def Stop(self): 103 | """Stops accepting requests from GUI clients.""" 104 | self._web_server.Stop() 105 | 106 | def Send(self, client_id, data): 107 | """Sends data to a GUI client of cliet_id.""" 108 | if client_id in self._clients: 109 | self._web_server.Send(client_id, data) 110 | 111 | def Broadcast(self, data): 112 | """Broadcasts data to all GUI clients connected now.""" 113 | for c in self._clients: 114 | self._web_server.Send(c, data) 115 | 116 | def _OnData(self, _, client_id, data): 117 | if client_id not in self._clients: 118 | logging.info('A new GUI client is connected: %s', str(client_id)) 119 | self._clients.add(client_id) 120 | logging.debug('Data from a GUI client: %s', str(client_id)) 121 | # TODO(byungchul): Handle incoming data and call observer accordingly. 122 | del data # unused 123 | 124 | def _OnError(self, _, client_id, error): 125 | logging.info('A GUI client is closed: %s, error=%s', str(client_id), error) 126 | self._clients.remove(client_id) 127 | -------------------------------------------------------------------------------- /gui/html/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sprockets GUI 4 | 5 | 6 | Hi, this is a place holder for sprockets GUI client page. 7 | 8 | 9 | -------------------------------------------------------------------------------- /gui/web_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2017 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """A web server to interact with GUI clients via http or websocket.""" 17 | 18 | import abc 19 | 20 | 21 | class WebServer(object): 22 | """An abstract class of web server to interact with GUI clients. 23 | 24 | Underlying implementation can be based on http or websocket, or support 25 | SSL or not. 26 | """ 27 | 28 | @abc.abstractmethod 29 | def Start(self, port, data_callback, error_callback, websocket_url, 30 | index_url, html_url, html_dir): 31 | """Starts the web server. 32 | 33 | Underlying implementation can be based on http or websocket, or support 34 | SSL or not. 35 | 36 | Args: 37 | port: tcp/ssl port for http or websocket. 38 | data_callback: a function called on incoming data from GUI clients. 39 | The arguments are (web_server, client_id, data) where 40 | web_server: this instance. 41 | client_id: an opaque ID or object for a GUI client for the incoming 42 | data or request. 43 | data: an incoming byte stream data from a GUI client. 44 | error_callback: a function called on any error from GUI clients which 45 | made the connection to the GUI client is invalid. The arguments are 46 | (web_server, client_id, error) where 47 | web_server: this instance. 48 | client_id: an opaque ID or object for a GUI client for the error. 49 | error: an error string. 50 | websocket_url: the absolute URL path of websocket or long-live http 51 | connection. 52 | index_url: the absolute URL path of main index.html. 53 | html_url: the absolute URL path of a directory serving static html or 54 | javascript resources. 55 | html_dir: the absolute file path of a directory corresponding to html_url. 56 | 57 | Raises: 58 | IOError: Cannot start a web server. 59 | """ 60 | 61 | @abc.abstractmethod 62 | def Stop(self): 63 | """Stops the web server and closes all connections to GUI clients.""" 64 | 65 | @abc.abstractmethod 66 | def Send(self, client_id, data): 67 | """Sends a data to a GUI client of |client_id|. 68 | 69 | Args: 70 | client_id: an opaque ID or object for a GUI client for the outgoing data 71 | or response. It must be gotten by callback call set by Start(). 72 | data: an outgoing byte stream data to a GUI client. 73 | 74 | Raises: 75 | IOError: Cannot send data to the GUI client. 76 | """ 77 | -------------------------------------------------------------------------------- /gui/websocket_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2017 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """A WebServer implementation based on websocket.""" 17 | 18 | import asyncio 19 | import functools 20 | import http 21 | import logging 22 | import os 23 | 24 | import gui.web_server 25 | import websockets 26 | 27 | 28 | class _GuiWebSocketServerProtocol(websockets.server.WebSocketServerProtocol): 29 | """Handles plain http requests as well as websocket.""" 30 | 31 | def __init__(self, websocket_url, index_url, html_url, html_dir, 32 | ws_handler, ws_server, **kwds): 33 | super().__init__(ws_handler, ws_server, **kwds) 34 | self._websocket_url = websocket_url 35 | self._index_url = index_url 36 | self._html_url = html_url + '/' 37 | self._html_dir = html_dir 38 | logging.debug('websocket_url=%s', self._websocket_url) 39 | logging.debug('html_url=%s', self._html_url) 40 | logging.debug('html_dir=%s', self._html_dir) 41 | 42 | @asyncio.coroutine 43 | def process_request(self, path, request_headers): 44 | if path == self._websocket_url: 45 | return None # Continue websocket handshake. 46 | if path == self._html_url or path == self._html_url[:-1]: 47 | return (http.HTTPStatus.PERMANENT_REDIRECT, 48 | [('Location', self._index_url)], None) 49 | if path.startswith(self._html_url): 50 | page = self._LoadPage(path[len(self._html_url):]) 51 | if page: 52 | return http.HTTPStatus.OK, [], page 53 | return http.HTTPStatus.NOT_FOUND, [], None 54 | 55 | def _LoadPage(self, path_tail): 56 | try: 57 | with open(os.path.join(self._html_dir, path_tail)) as f: 58 | return f.read().encode() 59 | except Exception as e: 60 | logging.debug(e) 61 | return None 62 | 63 | 64 | class WebSocketServer(gui.web_server.WebServer): 65 | """A GUI WebServer implementation based on websocket.""" 66 | 67 | def __init__(self): 68 | self._websocket_server = None 69 | self._port = None 70 | self._data_callback = None 71 | self._error_callback = None 72 | 73 | @asyncio.coroutine 74 | def _OnConnected(self, websocket, path): 75 | logging.debug('Websocket is connected: %s, path=%s', str(websocket), path) 76 | try: 77 | while True: 78 | data = yield from websocket.recv() 79 | logging.log(1, 'Got a data from a websocket: %s', str(websocket)) 80 | logging.log(1, 'data: %s', data) 81 | self._data_callback(self, websocket, data) 82 | except Exception as e: 83 | logging.debug(e) 84 | finally: 85 | logging.debug('Websocket is closed: %s', str(websocket)) 86 | self._error_callback(self, websocket, 'closed') 87 | 88 | def Start(self, port, data_callback, error_callback, websocket_url, 89 | index_url, html_url, html_dir): 90 | logging.debug('Starting a websocket server on port %d', port) 91 | self._port = port 92 | self._data_callback = data_callback 93 | self._error_callback = error_callback 94 | self._websocket_server = websockets.serve( 95 | self._OnConnected, port=self._port, 96 | create_protocol=functools.partial(_GuiWebSocketServerProtocol, 97 | websocket_url, index_url, 98 | html_url, html_dir)) 99 | # TODO(byungchul): Figure out a better thread model. 100 | asyncio.get_event_loop().run_until_complete(self._websocket_server) 101 | asyncio.get_event_loop().run_forever() 102 | 103 | def Stop(self): 104 | logging.debug('Stopping a websocket server on port %d', self._port) 105 | asyncio.get_event_loop().stop() 106 | 107 | def Send(self, websocket, data): 108 | logging.log(1, 'Sending a data to a websocket: %s', str(websocket)) 109 | logging.log(1, 'data: %s', data) 110 | asyncio.get_event_loop().create_task(websocket.send(data)) 111 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Requirements for sprockets 2 | mock == 2.0.0 3 | protobuf >= 3.0.0 4 | ply >= 3.8 5 | websockets >= 4.0.1 6 | networkx >= 1.11 7 | pygraphviz >= 1.3.1 --install-option="--include-path=/usr/include/graphviz" \ 8 | --install-option="--library-path=/usr/lib/graphviz/" 9 | -------------------------------------------------------------------------------- /sprockets_end_to_end_test.py: -------------------------------------------------------------------------------- 1 | """End-to-end tests for all of Sprockets.""" 2 | 3 | import os 4 | import shutil 5 | import tempfile 6 | import unittest 7 | 8 | import mock 9 | 10 | import test_driver 11 | 12 | @mock.patch('test_driver.Visualizer') 13 | class EndToEndTest(unittest.TestCase): 14 | 15 | def testSimpleExample(self, mock_visualizer): 16 | # RunTest returns True on success. 17 | self.assertTrue(test_driver.RunTest( 18 | 'end_to_end_test_data/simple_example.test', {})) 19 | 20 | def testDidYouMean_Transition(self, mock_visualizer): 21 | # The tConnectTlsActual transition has a a typo; raise an exception 22 | # with a helpful error message. 23 | with self.assertRaisesRegexp(NameError, 'Did you mean tConnectTls?'): 24 | test_driver.RunTest( 25 | 'end_to_end_test_data/did_you_mean_transition.test', {}) 26 | 27 | def testDidYouMean_StateValue(self, mock_visualizer): 28 | # The tDisconnectTls post_state has a typo; raise an exception 29 | # with a helpful error message. 30 | with self.assertRaisesRegexp(NameError, 'Did you mean kNotConnected?'): 31 | test_driver.RunTest( 32 | 'end_to_end_test_data/did_you_mean_state_value.test', {}) 33 | 34 | 35 | if __name__ == '__main__': 36 | unittest.main() 37 | -------------------------------------------------------------------------------- /stl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/sprockets/6d551a413dc7daed594439f6ab2fab4e91c4473f/stl/__init__.py -------------------------------------------------------------------------------- /stl/base_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2016 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """Tests for stl.base.""" 17 | # pylint: disable=invalid-name 18 | 19 | import unittest 20 | 21 | import stl.base 22 | 23 | 24 | class BaseTest(unittest.TestCase): 25 | 26 | def testConstEquality(self): 27 | a_bool_true = stl.base.Const('a', 'bool', stl.base.Value(True)) 28 | self.assertEqual(a_bool_true, 29 | stl.base.Const('a', 'bool', stl.base.Value(True))) 30 | 31 | a_bool_false = stl.base.Const('a', 'bool', stl.base.Value(False)) 32 | self.assertNotEqual(a_bool_true, a_bool_false) 33 | 34 | a_int_0 = stl.base.Const('a', 'int', stl.base.Value(0)) 35 | b_int_0 = stl.base.Const('b', 'int', stl.base.Value(0)) 36 | self.assertNotEqual(a_int_0, b_int_0) 37 | 38 | a_str_0 = stl.base.Const('a', 'string', stl.base.Value(0)) 39 | a_str_0str = stl.base.Const('a', 'string', stl.base.Value('0')) 40 | self.assertNotEqual(a_str_0, a_str_0str) 41 | 42 | self.assertNotEqual(a_bool_true, b_int_0) 43 | 44 | def testRoleEquality(self): 45 | rRoleEmpty = stl.base.Role('empty') 46 | self.assertEqual(rRoleEmpty, stl.base.Role('empty')) 47 | 48 | rRoleFields = stl.base.Role('fields') 49 | rRoleFields.fields = { 50 | 'a': stl.base.Field('a', 'int'), 51 | 'b': stl.base.Field('b', 'string') 52 | } 53 | rRoleFields2 = stl.base.Role('fields') 54 | rRoleFields2.fields = { 55 | 'a': stl.base.Field('a', 'int'), 56 | 'b': stl.base.Field('b', 'string') 57 | } 58 | self.assertEqual(rRoleFields, rRoleFields2) 59 | self.assertNotEqual(rRoleEmpty, rRoleFields) 60 | 61 | rRoleFieldsSameNameDifferentType = stl.base.Role('fields') 62 | rRoleFieldsSameNameDifferentType.fields = { 63 | 'a': stl.base.Field('a', 'bool'), 64 | 'b': stl.base.Field('b', 'int') 65 | } 66 | self.assertNotEqual(rRoleFields, rRoleFieldsSameNameDifferentType) 67 | 68 | rRoleMissingField = stl.base.Role('fields') 69 | rRoleMissingField.fields = {'a': stl.base.Field('a', 'int')} 70 | self.assertNotEqual(rRoleFields, rRoleMissingField) 71 | 72 | 73 | if __name__ == '__main__': 74 | unittest.main() 75 | -------------------------------------------------------------------------------- /stl/levenshtein.py: -------------------------------------------------------------------------------- 1 | """Module for calculating the Levenshtein distance bewtween two strings.""" 2 | 3 | def closest_candidate(target, candidates): 4 | """Returns the candidate that most closely matches |target|.""" 5 | return min(candidates, key=lambda candidate: distance(target, candidate)) 6 | 7 | 8 | def distance(a, b): 9 | """Returns the case-insensitive Levenshtein edit distance between |a| and |b|. 10 | 11 | The Levenshtein distance is a metric for measuring the difference between 12 | two strings. If |a| == |b|, the distance is 0. It is roughly the number 13 | of insertions, deletions, and substitutions needed to convert |a| -> |b|. 14 | 15 | This distance is at most the length of the longer string. 16 | This distance is 0 iff the strings are equal. 17 | 18 | Examples: 19 | levenshtein_distance("cow", "bow") == 1 20 | levenshtein_distance("cow", "bowl") == 2 21 | levenshtein_distance("cow", "blrp") == 4 22 | 23 | See https://en.wikipedia.org/wiki/Levenshtein_distance for more background. 24 | 25 | Args: 26 | a: A string 27 | b: A string 28 | 29 | Returns: 30 | The Levenshtein distance between the inputs. 31 | """ 32 | a = a.lower() 33 | b = b.lower() 34 | 35 | if len(a) == 0: 36 | return len(b) 37 | 38 | if len(b) == 0: 39 | return len(a) 40 | 41 | # Create 2D array[len(a)+1][len(b)+1] 42 | # | 0 b1 b2 b3 .. bN 43 | # ---+------------------- 44 | # 0 | 0 1 2 3 .. N 45 | # a1 | 1 0 0 0 .. 0 46 | # a2 | 2 0 0 0 .. 0 47 | # a3 | 3 0 0 0 .. 0 48 | # .. | . . . . .. . 49 | # aM | M 0 0 0 .. 0 50 | dist = [[0 for _ in range(len(b)+1)] for _ in range(len(a)+1)] 51 | for i in range(len(a)+1): 52 | dist[i][0] = i 53 | for j in range(len(b)+1): 54 | dist[0][j] = j 55 | 56 | # Build up the dist[][] table dynamically. At the end, the Levenshtein 57 | # distance between |a| and |b| will be in the bottom right cell. 58 | for i in range(1, len(a)+1): 59 | for j in range(1, len(b)+1): 60 | cost = 0 if a[i-1] == b[j-1] else 1 61 | dist[i][j] = min(dist[i-1][j] + 1, 62 | dist[i][j-1] + 1, 63 | dist[i-1][j-1] + cost) 64 | 65 | return dist[-1][-1] 66 | -------------------------------------------------------------------------------- /stl/levenshtein_test.py: -------------------------------------------------------------------------------- 1 | """Tests for levenshtein.""" 2 | 3 | import unittest 4 | 5 | import stl.levenshtein 6 | 7 | 8 | class LevenshteinTest(unittest.TestCase): 9 | 10 | def testEmpty(self): 11 | a = '' 12 | b = '' 13 | expected_distance = 0 14 | actual_distance = stl.levenshtein.distance(a, b) 15 | self.assertEqual(expected_distance, actual_distance) 16 | 17 | def testIdentical(self): 18 | a = 'xxxxx' 19 | b = 'xxxxx' 20 | expected_distance = 0 21 | actual_distance = stl.levenshtein.distance(a, b) 22 | self.assertEqual(expected_distance, actual_distance) 23 | 24 | def testIdentical_CaseInsensitive(self): 25 | a = 'xxxxx' 26 | b = 'xXxXx' 27 | expected_distance = 0 28 | actual_distance = stl.levenshtein.distance(a, b) 29 | self.assertEqual(expected_distance, actual_distance) 30 | 31 | def testOneLetter(self): 32 | a = 'a' 33 | b = 'b' 34 | expected_distance = 1 35 | actual_distance = stl.levenshtein.distance(a, b) 36 | self.assertEqual(expected_distance, actual_distance) 37 | 38 | def testAllDifferent_SameLength(self): 39 | a = 'abcde' 40 | b = 'vwxyz' 41 | expected_distance = 5 42 | actual_distance = stl.levenshtein.distance(a, b) 43 | self.assertEqual(expected_distance, actual_distance) 44 | 45 | def testAllDifferent_DifferentLength(self): 46 | a = 'abc' 47 | b = 'vwxyz' 48 | expected_distance = 5 49 | actual_distance = stl.levenshtein.distance(a, b) 50 | self.assertEqual(expected_distance, actual_distance) 51 | 52 | def testSomeDifferent_DifferentLength(self): 53 | a = 'abcd' 54 | b = 'axcxe' 55 | expected_distance = 3 56 | actual_distance = stl.levenshtein.distance(a, b) 57 | self.assertEqual(expected_distance, actual_distance) 58 | 59 | def testClosestCandidate_NoCandidates(self): 60 | with self.assertRaises(ValueError): 61 | stl.levenshtein.closest_candidate('', []) 62 | 63 | def testClosestCandidate_OneCadidate_ExactMatch(self): 64 | target = 'abc' 65 | candidates = ['abc'] 66 | expected_candidate = 'abc' 67 | actual_candidate = stl.levenshtein.closest_candidate(target, candidates) 68 | self.assertEqual(expected_candidate, actual_candidate) 69 | 70 | def testClosestCandidate_OneCandiate_NoExactMatch(self): 71 | target = 'abc' 72 | candidates = ['xyz'] 73 | expected_candidate = 'xyz' 74 | actual_candidate = stl.levenshtein.closest_candidate(target, candidates) 75 | self.assertEqual(expected_candidate, actual_candidate) 76 | 77 | def testClosestCandidate_MultipleCandidates_ExactMatch(self): 78 | target = 'abc' 79 | candidates = ['xyz', 'jkl', 'abcde', 'abc'] 80 | expected_candidate = 'abc' 81 | actual_candidate = stl.levenshtein.closest_candidate(target, candidates) 82 | self.assertEqual(expected_candidate, actual_candidate) 83 | 84 | def testClosestCandidate_MultipleCandidates_NoExactMatch(self): 85 | target = 'abc' 86 | candidates = ['xyz', 'jkl', 'abcde', 'abq'] 87 | expected_candidate = 'abq' 88 | actual_candidate = stl.levenshtein.closest_candidate(target, candidates) 89 | self.assertEqual(expected_candidate, actual_candidate) 90 | 91 | 92 | if __name__ == '__main__': 93 | unittest.main() 94 | -------------------------------------------------------------------------------- /stl/lexer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2016 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """Lexing (tokenizing) a state transition (STL) spec.""" 17 | 18 | # pylint: disable=g-doc-args 19 | # pylint: disable=g-docstring-missing-newline 20 | # pylint: disable=g-docstring-quotes 21 | # pylint: disable=g-no-space-after-docstring-summary 22 | # pylint: disable=g-short-docstring-punctuation 23 | # pylint: disable=g-short-docstring-space 24 | # pylint: disable=invalid-name 25 | # pylint: disable=unused-variable 26 | 27 | import logging 28 | import ply.lex # pylint: disable=g-bad-import-order 29 | 30 | 31 | class StlSyntaxError(SyntaxError): 32 | """Error for incorrect STL syntax.""" 33 | 34 | 35 | class StlLexer(object): 36 | 37 | def __init__(self, filename, error_handler, **kwargs): 38 | """Create a Lex lexer. 39 | 40 | To pass this into a Ply Yacc parser, pass it in using the .lexer propert 41 | of an StlLexer instance: 42 | my_lexer = StlLexer() 43 | my_parser = ply.yacc.parser(lexer=my_lexer.lexer) 44 | 45 | Args: 46 | filename: The filename string to use in any error messaging. 47 | error_handler: A object to handle and lexing errors. 48 | kwargs: Forwarded to ply.lex.lex. 49 | """ 50 | self._filename = filename 51 | self._error_handler = error_handler 52 | self.lexer = ply.lex.lex(module=self, **kwargs) 53 | 54 | RESERVED = { 55 | 'bool': 'BOOL', 56 | 'const': 'CONST', 57 | 'encode': 'ENCODE', 58 | 'error_states': 'ERROR_STATES', 59 | 'event': 'EVENT', 60 | 'events': 'EVENTS', 61 | 'external': 'EXTERNAL', 62 | 'int': 'INT', 63 | 'message': 'MESSAGE', 64 | 'module': 'MODULE', 65 | 'optional': 'OPTIONAL', 66 | 'post_states': 'POST_STATES', 67 | 'pre_states': 'PRE_STATES', 68 | 'qualifier': 'QUALIFIER', 69 | 'repeated': 'REPEATED', 70 | 'required': 'REQUIRED', 71 | 'role': 'ROLE', 72 | 'state': 'STATE', 73 | 'string': 'STRING', 74 | 'transition': 'TRANSITION', 75 | } 76 | 77 | # |literals| is a special field for ply.lex. Each of these 78 | # characters is interpreted as a separate token 79 | literals = ':;{}()[]=,.&' 80 | 81 | # |tokens| is a special field for ply.lex. This must contain a list 82 | # of all possible token types. 83 | tokens = [ 84 | 'ARROW', # -> 85 | 'BOOLEAN', 86 | 'NAME', 87 | 'NULL', 88 | 'NUMBER', 89 | 'STRING_LITERAL', 90 | ] + list(RESERVED.values()) 91 | 92 | # A string containing ignored characters (spaces and tabs) 93 | t_ignore = ' \t' 94 | 95 | def t_ARROW(self, t): 96 | r'->' 97 | return t 98 | 99 | def t_BOOLEAN(self, t): 100 | r'(true|false)' 101 | t.value = (t.value == 'true') 102 | return t 103 | 104 | def t_NULL(self, t): 105 | r'null' 106 | t.value = None 107 | return t 108 | 109 | def t_NAME(self, t): 110 | r'[a-zA-Z_]\w*' 111 | t.type = self.RESERVED.get(t.value, 'NAME') 112 | return t 113 | 114 | def t_NUMBER(self, t): 115 | r'-?\d+' 116 | t.value = int(t.value) 117 | return t 118 | 119 | def t_STRING_LITERAL(self, t): 120 | r'"([^\\"]|\\"|\\\\)*"' 121 | t.value = t.value[1:-1].replace('\\"', '"').replace('\\\\', '\\') 122 | return t 123 | 124 | def t_COMMENT(self, t): 125 | r'//.*' 126 | del t # unused argument 127 | 128 | # Define a rule so we can track line numbers. 129 | def t_newline(self, t): 130 | r'\n+' 131 | t.lexer.lineno += len(t.value) 132 | 133 | # Error handling rule. 134 | def t_error(self, t): 135 | print(self._error_handler.GetError(self._filename, t)) 136 | raise StlSyntaxError('Error while lexing.') 137 | 138 | def debug(data): 139 | """Print out all the tokens in |data|.""" 140 | for token in self.lexer.tokens(): 141 | print(token) 142 | -------------------------------------------------------------------------------- /stl/lexer_error.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Module for matching specific errors from the lexer.""" 16 | 17 | 18 | class LexerError(object): 19 | """Class for describing and matching errors from the lexer.""" 20 | 21 | def __init__(self, error_name, error_id, error_msg, token_value): 22 | """Create a LexerError that matches |token_value|. 23 | 24 | Args: 25 | error_name: A short, human readable name for the error, 26 | using lowercase-with-dashes-format. 27 | error_id: An integer to identify a specific error: 28 | 100s: Lexer errors. 29 | 200s: Low level parsing errors. 30 | 300s: High level parsing errors. 31 | error_msg: A message to display with this error that describes 32 | clearly what caused the error. 33 | token_value: A string to match against the token that the lexer 34 | failed at (or None to match against every token). 35 | 36 | Returns: 37 | LexerError that matches against |token_value|. 38 | """ 39 | self.error_name = error_name 40 | self.error_id = error_id 41 | self.error_msg = error_msg 42 | self._token_value = token_value 43 | 44 | def Matches(self, token): 45 | return self._token_value is None or token.value == self._token_value 46 | -------------------------------------------------------------------------------- /stl/message_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2016 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """Tests for stl.message.""" 17 | # pylint: disable=invalid-name 18 | 19 | import unittest 20 | 21 | import stl.base 22 | import stl.message 23 | 24 | 25 | class MessageTest(unittest.TestCase): 26 | 27 | def testMessageEquality_NoNesting(self): 28 | mSimpleJsonMsg = stl.message.Message( 29 | 'mSimpleJsonMsg', 'stl.lib.JsonEncoding', is_array=False) 30 | mSimpleJsonMsg.fields = [ 31 | stl.base.Field('msg', 'string'), 32 | stl.base.Field('id', 'int', optional=True), 33 | stl.base.Field('bits', 'bool', repeated=True) 34 | ] 35 | 36 | mSimpleJsonMsg2 = stl.message.Message( 37 | 'mSimpleJsonMsg', 'stl.lib.JsonEncoding', is_array=False) 38 | mSimpleJsonMsg2.fields = [ 39 | stl.base.Field('msg', 'string'), 40 | stl.base.Field('id', 'int', optional=True), 41 | stl.base.Field('bits', 'bool', repeated=True) 42 | ] 43 | self.assertEqual(mSimpleJsonMsg, mSimpleJsonMsg2) 44 | 45 | mSimpleProtobufMsg = stl.message.Message( 46 | 'mSimpleProtobufMsg', 'stl.lib.ProtobufEncoding', is_array=False) 47 | mSimpleProtobufMsg.fields = [ 48 | stl.base.Field('foo', 'string'), 49 | stl.base.Field('fizz', 'int', optional=True), 50 | stl.base.Field('buzz', 'bool', repeated=True) 51 | ] 52 | 53 | self.assertNotEqual(mSimpleJsonMsg, mSimpleProtobufMsg) 54 | 55 | def testMessageEquality_WithNesting(self): 56 | mInnerMsg = stl.message.Message('mInnerMsg', None, is_array=False) 57 | mInnerMsg.fields = [ 58 | stl.base.Field('in', 'string'), 59 | stl.base.Field('k', 'int') 60 | ] 61 | 62 | mExtraMsg = stl.message.Message('mExtraMsg', None, is_array=False) 63 | mExtraMsg.fields = [stl.base.Field('nums', 'int', repeated=True)] 64 | 65 | mNestedJsonMsg = stl.message.Message( 66 | 'mNestedJsonMsg', 'stl.lib.JsonEncoding', is_array=False) 67 | mNestedJsonMsg.fields = [ 68 | stl.base.Field('inner', 'mInnerMsg'), 69 | stl.base.Field('extra', 'mExtraMsg', optional=True) 70 | ] 71 | mNestedJsonMsg.messages = {'mInnerMsg': mInnerMsg, 'mExtraMsg': mExtraMsg} 72 | 73 | mNestedJsonMsg2 = stl.message.Message( 74 | 'mNestedJsonMsg', 'stl.lib.JsonEncoding', is_array=False) 75 | mNestedJsonMsg2.fields = [ 76 | stl.base.Field('inner', 'mInnerMsg'), 77 | stl.base.Field('extra', 'mExtraMsg', optional=True) 78 | ] 79 | mNestedJsonMsg2.messages = { 80 | 'mInnerMsg': mInnerMsg, 81 | 'mExtraMsg': mExtraMsg 82 | } 83 | 84 | self.assertEqual(mNestedJsonMsg, mNestedJsonMsg2) 85 | 86 | mNestedJsonMsg2.messages = {'mInnerMsg': mInnerMsg} 87 | self.assertNotEqual(mNestedJsonMsg, mNestedJsonMsg2) 88 | 89 | mNestedJsonMsg2.messages = { 90 | 'mInnerMsg': mInnerMsg, 91 | 'mExtraMsg': mExtraMsg 92 | } 93 | mNestedJsonMsg2.fields = [stl.base.Field('inner', 'mInnerMsg')] 94 | self.assertNotEqual(mNestedJsonMsg, mNestedJsonMsg2) 95 | 96 | 97 | if __name__ == '__main__': 98 | unittest.main() 99 | -------------------------------------------------------------------------------- /stl/module.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """Container for STL modules.""" 15 | 16 | 17 | class Module(object): 18 | """STL Module. 19 | 20 | A module is a namespaced set of STL components. Every STL file must be 21 | prefaced with a module name. For example: 22 | 23 | module my_module; 24 | 25 | Attributes: 26 | name: The name of this module. 27 | consts: Dictionary of stl.base.Const 28 | roles: Dictionary of stl.base.Role 29 | states: Dictionary of stl.state.State 30 | qualifiers: Dictionary of stl.qualifier.Qualifier 31 | messages: Dictionary of stl.message.Message 32 | events: Dictionary of stl.event.Event 33 | transitions: Dictionary of stl.state.Transition 34 | """ 35 | 36 | def __init__(self, name): 37 | self.name = name 38 | self.consts = {} 39 | self.roles = {} 40 | self.states = {} 41 | self.qualifiers = {} 42 | self.messages = {} 43 | self.events = {} 44 | self.transitions = {} 45 | 46 | def __eq__(self, other): 47 | return (isinstance(other, Module) and self.name == other.name and 48 | self.consts == other.consts and self.roles == other.roles and 49 | self.states == other.states and 50 | self.qualifiers == other.qualifiers and 51 | self.messages == other.messages and self.events == other.events and 52 | self.transitions == other.transitions) 53 | 54 | def HasDefinition(self, name): 55 | """Whether this module has a named object |name|. 56 | 57 | Args: 58 | name: The string name of the object to look for. 59 | 60 | Returns: 61 | True if this module has an object with name |name|, False otherwise. 62 | """ 63 | return (name in self.consts or name in self.roles or name in self.states or 64 | name in self.qualifiers or name in self.messages or 65 | name in self.events or name in self.transitions) 66 | -------------------------------------------------------------------------------- /stl/parser_error.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Module for matching specific errors from the parser.""" 16 | 17 | 18 | class ParserError(object): 19 | """Class for describing and matching errors from the parser.""" 20 | 21 | def __init__(self, error_name, error_id, error_msg, stack_patterns): 22 | """Create a ParserError that matches against any of the |stack_patterns|. 23 | 24 | Args: 25 | error_name: A short, human readable name for the error, 26 | using lowercase-with-dashes-format. 27 | error_id: An integer to identify a specific error: 28 | 100s: Lexer errors. 29 | 200s: Low level parsing errors. 30 | 300s: High level parsing errors. 31 | error_msg: A message to display with this error that describes 32 | clearly what caused the error. 33 | stack_patterns: A list of "stack patterns", where each stack pattern 34 | is a list of strings corresponding to symbols on the parser's symbol 35 | stack at the time it errored out. The string values for the symbols 36 | can match essentially any terminal or non-terminal symbol used in the 37 | grammar from parser.py. 38 | Examples: ['TRANSITION', 'NAME', 'params', '='] 39 | (or None to match against any symbol stack). 40 | 41 | Returns: 42 | ParserError that matches against |stack_patterns|. 43 | """ 44 | self.error_name = error_name 45 | self.error_id = error_id 46 | self.error_msg = error_msg 47 | self._stack_patterns = stack_patterns 48 | 49 | def Matches(self, parser): 50 | if self._stack_patterns is None: 51 | return True 52 | 53 | return any(self._SymbolStackEndsWith(parser.symstack, stack_pattern) 54 | for stack_pattern in self._stack_patterns) 55 | 56 | def _SymbolStackEndsWith(self, parser_symbol_stack, stack_pattern): 57 | """Determines if |stack| matches against |symbol_stack|. 58 | 59 | Args: 60 | symbol_stack: The symbol stack from parser.symstack left on th parser 61 | when an error was generarted. 62 | stack: A list of strings to match against the token 'type' in 63 | |symbol_stack|. (e.g. ['TRANSITION', 'NAME', 'params', '='] 64 | """ 65 | parser_symbol_stack_str = ' '.join(s.type for s in parser_symbol_stack) 66 | stack_pattern_str = ' '.join(stack_pattern) 67 | return parser_symbol_stack_str.endswith(stack_pattern_str) 68 | -------------------------------------------------------------------------------- /stl/parser_test_proto.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // A proto file for stl unittests. 16 | 17 | syntax = "proto2"; 18 | 19 | option optimize_for = LITE_RUNTIME; 20 | 21 | package bar; 22 | 23 | message SimpleMsg { 24 | required string foo = 1; 25 | optional int32 fizz = 2; 26 | repeated bool buzz = 3; 27 | } 28 | -------------------------------------------------------------------------------- /stl/parser_test_proto_pb2.py: -------------------------------------------------------------------------------- 1 | # Generated by the protocol buffer compiler. DO NOT EDIT! 2 | # source: parser_test_proto.proto 3 | 4 | import sys 5 | _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import message as _message 8 | from google.protobuf import reflection as _reflection 9 | from google.protobuf import symbol_database as _symbol_database 10 | from google.protobuf import descriptor_pb2 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | 17 | 18 | DESCRIPTOR = _descriptor.FileDescriptor( 19 | name='parser_test_proto.proto', 20 | package='bar', 21 | syntax='proto2', 22 | serialized_pb=_b('\n\x17parser_test_proto.proto\x12\x03\x62\x61r\"4\n\tSimpleMsg\x12\x0b\n\x03\x66oo\x18\x01 \x02(\t\x12\x0c\n\x04\x66izz\x18\x02 \x01(\x05\x12\x0c\n\x04\x62uzz\x18\x03 \x03(\x08\x42\x02H\x03') 23 | ) 24 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 25 | 26 | 27 | 28 | 29 | _SIMPLEMSG = _descriptor.Descriptor( 30 | name='SimpleMsg', 31 | full_name='bar.SimpleMsg', 32 | filename=None, 33 | file=DESCRIPTOR, 34 | containing_type=None, 35 | fields=[ 36 | _descriptor.FieldDescriptor( 37 | name='foo', full_name='bar.SimpleMsg.foo', index=0, 38 | number=1, type=9, cpp_type=9, label=2, 39 | has_default_value=False, default_value=_b("").decode('utf-8'), 40 | message_type=None, enum_type=None, containing_type=None, 41 | is_extension=False, extension_scope=None, 42 | options=None), 43 | _descriptor.FieldDescriptor( 44 | name='fizz', full_name='bar.SimpleMsg.fizz', index=1, 45 | number=2, type=5, cpp_type=1, label=1, 46 | has_default_value=False, default_value=0, 47 | message_type=None, enum_type=None, containing_type=None, 48 | is_extension=False, extension_scope=None, 49 | options=None), 50 | _descriptor.FieldDescriptor( 51 | name='buzz', full_name='bar.SimpleMsg.buzz', index=2, 52 | number=3, type=8, cpp_type=7, label=3, 53 | has_default_value=False, default_value=[], 54 | message_type=None, enum_type=None, containing_type=None, 55 | is_extension=False, extension_scope=None, 56 | options=None), 57 | ], 58 | extensions=[ 59 | ], 60 | nested_types=[], 61 | enum_types=[ 62 | ], 63 | options=None, 64 | is_extendable=False, 65 | syntax='proto2', 66 | extension_ranges=[], 67 | oneofs=[ 68 | ], 69 | serialized_start=32, 70 | serialized_end=84, 71 | ) 72 | 73 | DESCRIPTOR.message_types_by_name['SimpleMsg'] = _SIMPLEMSG 74 | 75 | SimpleMsg = _reflection.GeneratedProtocolMessageType('SimpleMsg', (_message.Message,), dict( 76 | DESCRIPTOR = _SIMPLEMSG, 77 | __module__ = 'parser_test_proto_pb2' 78 | # @@protoc_insertion_point(class_scope:bar.SimpleMsg) 79 | )) 80 | _sym_db.RegisterMessage(SimpleMsg) 81 | 82 | 83 | DESCRIPTOR.has_options = True 84 | DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('H\003')) 85 | # @@protoc_insertion_point(module_scope) 86 | -------------------------------------------------------------------------------- /stl/qualifier.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Defines qualifier for message fields.""" 16 | 17 | import importlib 18 | import logging 19 | 20 | import stl.base 21 | 22 | 23 | # TODO(seantopping): Support expanded qualifiers. 24 | class Qualifier(stl.base.ParameterizedObject): 25 | """Field qualifier for messages. 26 | 27 | A user defined qualifier must inherit from stl.lib.Qualifier. Qualifiers 28 | are used to validate and generate values for message fields. 29 | 30 | Attributes: 31 | qual_type: The field type to be qualified (int, bool, string, message). 32 | """ 33 | 34 | def __init__(self, name, qual_type): 35 | stl.base.ParameterizedObject.__init__(self, name) 36 | self.qual_type = qual_type 37 | 38 | def __eq__(self, other): 39 | return (stl.base.ParameterizedObject.__eq__(self, other) and 40 | self.qual_type == other.qual_type) 41 | 42 | def __str__(self): 43 | return 'Qualifier %s: p(%s)' % (self.name, stl.base.GetCSV(self.params)) 44 | 45 | 46 | class QualifierFromExternal(Qualifier): 47 | """Wraps an external qualifier defined in a python file. 48 | 49 | Example: 50 | qualifier int RandomInt() = external "foo.bar.RandomInt"; 51 | 52 | There should be a python module "foo.bar" with a class RandomInt that inherits 53 | stl.lib.Qualifier. 54 | 55 | Attributes: 56 | external_name: Name of class that extends stl.lib.Qualifier. 57 | external: An instance of the stl.lib.Qualifier class. 58 | """ 59 | 60 | def __init__(self, name, qual_type, external): 61 | Qualifier.__init__(self, name, qual_type) 62 | self.external_name = external 63 | module, event = external.rsplit('.', 1) 64 | self.external = importlib.import_module(module).__getattribute__(event)() 65 | 66 | def __eq__(self, other): 67 | return (Qualifier.__eq__(self, other) and 68 | self.external_name == other.external_name) 69 | 70 | def __str__(self): 71 | return '%s b(%s)' % (Qualifier.__str__(self), self.external_name) 72 | 73 | def Resolve(self, env, resolved_params): 74 | logging.log(1, 'Resolving ' + self.name) 75 | return self.external 76 | -------------------------------------------------------------------------------- /stl/state_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2016 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | """Tests for stl.state.""" 17 | # pylint: disable=invalid-name 18 | 19 | import unittest 20 | 21 | import stl.base 22 | import stl.state 23 | 24 | 25 | class StateTest(unittest.TestCase): 26 | 27 | def testStateEquality(self): 28 | sSimpleState = stl.state.State('sSimpleState') 29 | sSimpleState.values = ['kValue1'] 30 | 31 | sSimpleState2 = stl.state.State('sSimpleState') 32 | sSimpleState2.values = ['kValue1'] 33 | 34 | self.assertEqual(sSimpleState, sSimpleState2) 35 | 36 | sSimpleState2.values = ['DIFFERENT'] 37 | self.assertNotEqual(sSimpleState, sSimpleState2) 38 | 39 | sSimpleState2.values = ['kValue1', 'kValue2'] 40 | self.assertNotEqual(sSimpleState, sSimpleState2) 41 | 42 | sWithSingleParamState = stl.state.State('sWithSingleParamState') 43 | sWithSingleParamState.values = ['kValue1', 'kValue2', 'kValue3'] 44 | sWithSingleParamState.params = [stl.base.Param('param', 'int')] 45 | 46 | sWithSingleParamState2 = stl.state.State('sWithSingleParamState') 47 | sWithSingleParamState2.values = ['kValue1', 'kValue2', 'kValue3'] 48 | sWithSingleParamState2.params = [stl.base.Param('param', 'int')] 49 | 50 | self.assertEqual(sWithSingleParamState, sWithSingleParamState2) 51 | 52 | sWithSingleParamState2.params = [] 53 | self.assertNotEqual(sWithSingleParamState, sWithSingleParamState2) 54 | 55 | sWithSingleParamState2.params = [stl.base.Param('param', 'bool')] 56 | self.assertNotEqual(sWithSingleParamState, sWithSingleParamState2) 57 | 58 | sWithMultipleParams = stl.state.State('sWithMultipleParams') 59 | sWithMultipleParams.values = ['kValue1', 'kValue2'] 60 | sWithMultipleParams.params = [stl.base.Param('param1', 'int'), 61 | stl.base.Param('param2', 'role'), 62 | stl.base.Param('msg', 'string')] 63 | 64 | sWithMultipleParams2 = stl.state.State('sWithMultipleParams') 65 | sWithMultipleParams2.values = ['kValue1', 'kValue2'] 66 | sWithMultipleParams2.params = [stl.base.Param('param1', 'int'), 67 | stl.base.Param('param2', 'role'), 68 | stl.base.Param('msg', 'string')] 69 | 70 | self.assertEqual(sWithMultipleParams, sWithMultipleParams2) 71 | 72 | sWithMultipleParams2.values = ['kValue0', 'kValue1', 'kValue2'] 73 | self.assertNotEqual(sWithMultipleParams, sWithMultipleParams2) 74 | 75 | sWithMultipleParams2.values = ['kValue1', 'kValue2'] 76 | sWithMultipleParams2.params = [stl.base.Param('param1', 'int'), 77 | stl.base.Param('msg', 'string'), 78 | stl.base.Param('param2', 'role')] 79 | self.assertNotEqual(sWithMultipleParams, sWithMultipleParams2) 80 | 81 | 82 | if __name__ == '__main__': 83 | unittest.main() 84 | --------------------------------------------------------------------------------