1#!/usr/bin/env python3 2# Copyright 2020 The Pigweed Authors 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); you may not 5# use this file except in compliance with the License. You may obtain a copy of 6# the License at 7# 8# https://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, WITHOUT 12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13# License for the specific language governing permissions and limitations under 14# the License. 15"""pw_protobuf compiler plugin. 16 17This file implements a protobuf compiler plugin which generates C++ headers for 18protobuf messages in the pw_protobuf format. 19""" 20 21import sys 22 23import google.protobuf.compiler.plugin_pb2 as plugin_pb2 24 25import pw_protobuf.codegen_pwpb as codegen_pwpb 26 27 28def process_proto_request(req: plugin_pb2.CodeGeneratorRequest, 29 res: plugin_pb2.CodeGeneratorResponse) -> None: 30 """Handles a protoc CodeGeneratorRequest message. 31 32 Generates code for the files in the request and writes the output to the 33 specified CodeGeneratorResponse message. 34 35 Args: 36 req: A CodeGeneratorRequest for a proto compilation. 37 res: A CodeGeneratorResponse to populate with the plugin's output. 38 """ 39 for proto_file in req.proto_file: 40 output_files = codegen_pwpb.process_proto_file(proto_file) 41 for output_file in output_files: 42 fd = res.file.add() 43 fd.name = output_file.name() 44 fd.content = output_file.content() 45 46 47def main() -> int: 48 """Protobuf compiler plugin entrypoint. 49 50 Reads a CodeGeneratorRequest proto from stdin and writes a 51 CodeGeneratorResponse to stdout. 52 """ 53 data = sys.stdin.buffer.read() 54 request = plugin_pb2.CodeGeneratorRequest.FromString(data) 55 response = plugin_pb2.CodeGeneratorResponse() 56 process_proto_request(request, response) 57 58 # Declare that this plugin supports optional fields in proto3. 59 response.supported_features |= ( # type: ignore[attr-defined] 60 response.FEATURE_PROTO3_OPTIONAL) # type: ignore[attr-defined] 61 62 sys.stdout.buffer.write(response.SerializeToString()) 63 return 0 64 65 66if __name__ == '__main__': 67 sys.exit(main()) 68