Index: third_party/dom_distiller_js/protoc_plugins/util/plugin_protos.py |
diff --git a/third_party/dom_distiller_js/protoc_plugins/util/plugin_protos.py b/third_party/dom_distiller_js/protoc_plugins/util/plugin_protos.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..57de59fa4396951b353f4e70573a707aa9e60f1d |
--- /dev/null |
+++ b/third_party/dom_distiller_js/protoc_plugins/util/plugin_protos.py |
@@ -0,0 +1,284 @@ |
+# Copyright 2016 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+""" |
+Provides simple state-less wrappers of the proto types used by plugins. |
+ |
+See https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor.pb |
+and https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.compiler.plugin.pb |
+""" |
+ |
+import os |
+import sys |
+ |
+from google.protobuf.descriptor_pb2 import FieldDescriptorProto |
+ |
+import plugin |
+import types |
+ |
+sys.path.insert( |
+ 1, os.path.join(os.path.dirname(__file__), '..', '..', |
+ 'dist', 'python')) |
+import plugin_pb2 |
+ |
+ |
+class PluginRequest(object): |
+ def __init__(self, proto): |
+ self.proto = proto |
+ |
+ def GetArgs(self): |
+ return dict((v.split('=') for v in self.proto.parameter.split(','))) |
+ |
+ def GetAllFiles(self): |
+ all = map(ProtoFile, self.proto.proto_file) |
+ for f in all: |
+ assert f.Filename() in self.proto.file_to_generate |
+ return all |
+ |
+ |
+def PluginRequestFromString(data): |
+ request_proto = plugin_pb2.CodeGeneratorRequest() |
+ request_proto.ParseFromString(data) |
+ return PluginRequest(request_proto) |
+ |
+ |
+class PluginResponse(object): |
+ def __init__(self): |
+ self.proto = plugin_pb2.CodeGeneratorResponse() |
+ |
+ def AddFileWithContent(self, filename, content): |
+ file_proto = self.proto.file.add() |
+ file_proto.name = filename |
+ file_proto.content = content |
+ |
+ def AddError(self, err): |
+ self.proto.error += err + '\n' |
+ |
+ def WriteToStdout(self): |
+ sys.stdout.write(self.proto.SerializeToString()) |
+ sys.stdout.flush() |
+ |
+ |
+class ProtoFile(object): |
+ def __init__(self, proto): |
+ self.proto = proto |
+ self.qualified_types = types.QualifiedTypes( |
+ self.ProtoPackage(), |
+ self.JavaPackage() + '.' + self.JavaOuterClass(), |
+ self.CppBaseNamespace(), |
+ self.CppConverterNamespace() |
+ ) |
+ |
+ def Filename(self): |
+ return self.proto.name |
+ |
+ def CheckSupported(self): |
+ if self.proto.service: |
+ return 'Services are not supported' |
+ |
+ if self.proto.extension: |
+ return 'Extensions are not supported' |
+ |
+ for child in self.GetMessages() + self.GetEnums(): |
+ err = child.CheckSupported() |
+ if err: |
+ return err |
+ |
+ def ProtoPackage(self): |
+ return self.proto.package if self.proto.HasField('package') else '' |
+ |
+ def ProtoNamespaces(self): |
+ return self.ProtoPackage().split('.') |
+ |
+ def CppBaseNamespace(self): |
+ return '::'.join(self.ProtoNamespaces()) |
+ |
+ def CppBaseHeader(self): |
+ assert self.proto.name.endswith('.proto') |
+ return self.proto.name[:-5] + 'pb.h' |
+ |
+ def CppConverterNamespace(self): |
+ return self.CppBaseNamespace() + '::json' |
+ |
+ def JavaPackage(self): |
+ if self.proto.options.HasField('java_package'): |
+ return self.proto.options.java_package |
+ else: |
+ return self.ProtoPackage() |
+ |
+ def GetMessages(self): |
+ return [ProtoMessage(n, self.qualified_types) |
+ for n in self.proto.message_type] |
+ |
+ def GetEnums(self): |
+ return [ProtoEnum(n, self.qualified_types) for n in self.proto.enum_type] |
+ |
+ def GetDependencies(self): |
+ return map(plugin.GetProtoFileForFilename, self.proto.dependency) |
+ |
+ def JavaFilename(self): |
+ return '/'.join(self.JavaQualifiedOuterClass().split('.')) + '.java' |
+ |
+ def JavaOuterClass(self): |
+ if self.proto.options.HasField('java_outer_classname'): |
+ return self.proto.options.java_outer_classname |
+ basename, _ = os.path.splitext(os.path.basename(self.proto.name)) |
+ return plugin.TitleCase(basename) |
+ |
+ def JavaQualifiedOuterClass(self): |
+ return self.qualified_types.java |
+ |
+ def CppConverterFilename(self): |
+ assert self.proto.name.endswith('.proto') |
+ return self.proto.name[:-6] + '_json_converter.h' |
+ |
+ |
+class ProtoMessage(object): |
+ def __init__(self, proto, parent_typenames): |
+ self.proto = proto |
+ self.qualified_types = types.QualifiedTypesForChild( |
+ proto.name, parent_typenames) |
+ |
+ def CheckSupported(self): |
+ if self.proto.extension_range: |
+ return 'Extensions are not supported: ' + self.proto.extension_range |
+ |
+ for child in self.GetFields() + self.GetMessages() + self.GetEnums(): |
+ err = child.CheckSupported() |
+ if err: |
+ return err |
+ |
+ def QualifiedTypes(self): |
+ return self.qualified_types |
+ |
+ def JavaClassName(self): |
+ return plugin.TitleCase(self.proto.name) |
+ |
+ def CppConverterClassName(self): |
+ return plugin.TitleCase(self.proto.name) |
+ |
+ def GetFields(self): |
+ return map(ProtoField, self.proto.field) |
+ |
+ def GetMessages(self): |
+ return [ProtoMessage(n, self.qualified_types) |
+ for n in self.proto.nested_type] |
+ |
+ def GetEnums(self): |
+ return [ProtoEnum(n, self.qualified_types) for n in self.proto.enum_type] |
+ |
+ |
+class ProtoField(object): |
+ def __init__(self, field_proto): |
+ self.proto = field_proto |
+ self.name = field_proto.name |
+ |
+ if self.IsClassType() and not self.proto.HasField('type_name'): |
+ raise Error('expected type_name') |
+ |
+ def Extendee(self): |
+ return self.proto.extendee if self.proto.HasField('extendee') else None |
+ |
+ def IsOptional(self): |
+ return self.proto.label == FieldDescriptorProto.LABEL_OPTIONAL |
+ |
+ def IsRepeated(self): |
+ return self.proto.label == FieldDescriptorProto.LABEL_REPEATED |
+ |
+ def IsRequired(self): |
+ return self.proto.label == FieldDescriptorProto.LABEL_REQUIRED |
+ |
+ def IsClassType(self): |
+ return self.proto.type == FieldDescriptorProto.TYPE_MESSAGE |
+ |
+ def IsEnumType(self): |
+ return self.proto.type == FieldDescriptorProto.TYPE_ENUM |
+ |
+ def JavaType(self): |
+ if self.IsClassType(): |
+ return types.ResolveJavaClassType(self.proto.type_name) |
+ elif self.IsEnumType(): |
+ return 'int' |
+ else: |
+ return types.GetJavaPrimitiveType(self.proto.type) |
+ |
+ def JavaListType(self): |
+ return types.GetJavaObjectType(self.JavaType()) |
+ |
+ def JavascriptIndex(self): |
+ return self.proto.number |
+ |
+ def JavaName(self): |
+ return plugin.TitleCase(self.name) |
+ |
+ def CppConverterType(self): |
+ return types.ResolveCppConverterType(self.proto.type_name) |
+ |
+ def CppPrimitiveType(self): |
+ assert not self.IsClassType() |
+ return types.GetCppPrimitiveType(self.proto.type) |
+ |
+ def CppValueType(self): |
+ return types.GetCppValueType(self.CppPrimitiveType()) |
+ |
+ def CheckSupported(self): |
+ if self.Extendee(): |
+ return 'Unsupported field extension: ' + self.DebugString() |
+ |
+ if self.JavaType() is None: |
+ return 'Unsupported type for field: ' + self.DebugString() |
+ |
+ if self.IsRequired(): |
+ return 'Required fields not supported: ' + self.DebugString() |
+ |
+ if self.proto.HasField('default_value'): |
+ return 'Default values are not supported: ' + self.DebugString() |
+ |
+ return None |
+ |
+ def DebugString(self): |
+ return '{name}, {type}, {extendee}'.format( |
+ name=self.name, |
+ type=self.proto.type, |
+ extendee=self.Extendee()) |
+ |
+ |
+class ProtoEnum(object): |
+ def __init__(self, proto, parent_typenames): |
+ self.proto = proto |
+ self.qualified_types = types.QualifiedTypesForChild( |
+ proto.name, parent_typenames) |
+ |
+ def CheckSupported(self): |
+ if self.proto.HasField('options'): |
+ return 'Enum options are not supported: ' + self.DebugString() |
+ for val in self.Values(): |
+ err = val.CheckSupported() |
+ if err: |
+ return err + ' ' + self.DebugString() |
+ |
+ def QualifiedTypes(self): |
+ return self.qualified_types |
+ |
+ def JavaName(self): |
+ return plugin.TitleCase(self.proto.name) |
+ |
+ def Values(self): |
+ return map(ProtoEnumValue, self.proto.value) |
+ |
+ |
+class ProtoEnumValue(object): |
+ def __init__(self, enum_value_proto): |
+ self.proto = enum_value_proto |
+ |
+ def GetName(self): |
+ return self.proto.name |
+ |
+ def GetValue(self): |
+ return self.proto.number |
+ |
+ def CheckSupported(self): |
+ if self.proto.HasField('options'): |
+ return 'Enum value options are not supported: {} {}'.format( |
+ self.proto.name, self.proto.value) |