func (p *protoBufErrors) lintProtoMessage( pathIndex int32, pathType int32, parentPath []int32, protoMessage *descriptor.DescriptorProto, ) { path := append( parentPath, pathType, pathIndex, ) if !isCamelCase(protoMessage.GetName()) { p.addError(&protoBufError{ path: path, errorCode: errorMessageCase, errorString: protoMessage.GetName(), }) } for i, v := range protoMessage.GetField() { p.lintProtoField(int32(i), path, v) } for i, v := range protoMessage.GetEnumType() { p.lintProtoEnumType(int32(i), pathMessageEnum, path, v) } for i, v := range protoMessage.GetNestedType() { p.lintProtoMessage(int32(i), pathMessageMessage, path, v) } }
func getTmplMessageDatas(pkg string, parents []string, messageType *descriptor.DescriptorProto, messageDatas []*tmplMessageData) []*tmplMessageData { protoName := pkg for _, parent := range parents { protoName = protoName + "." + parent } name := messageType.GetName() protoName = protoName + "." + name goName := name for i := len(parents) - 1; i >= 0; i-- { goName = parents[i] + "_" + goName } messageDatas = append( messageDatas, &tmplMessageData{ ProtoName: protoName, GoName: goName, }, ) for _, child := range messageType.NestedType { if child.Options == nil || !child.Options.GetMapEntry() { messageDatas = getTmplMessageDatas( pkg, append(parents, name), child, messageDatas, ) } } return messageDatas }
func fillTreeWithMessage(tree *tree, key string, proto *descriptor.DescriptorProto, loc string, locs map[string]*descriptor.SourceCodeInfo_Location) *message { key = fmt.Sprintf("%s.%s", key, proto.GetName()) tree.messages[key] = &message{key: key, comment: getComment(loc, locs), DescriptorProto: proto} // Oneofs for idx, proto := range proto.GetOneofDecl() { tree.messages[key].oneofs = append(tree.messages[key].oneofs, &oneof{ index: int32(idx), OneofDescriptorProto: proto, }) } // Fields for idx, proto := range proto.GetField() { field := fillTreeWithField(tree, key, proto, fmt.Sprintf("%s,2,%d", loc, idx), locs) tree.messages[key].fields = append(tree.messages[key].fields, field) } // Nested for idx, proto := range proto.GetNestedType() { message := fillTreeWithMessage(tree, key, proto, fmt.Sprintf("%s,3,%d", loc, idx), locs) tree.messages[key].nested = append(tree.messages[key].nested, message) } // Enums for idx, proto := range proto.GetEnumType() { fillTreeWithEnum(tree, key, proto, fmt.Sprintf("%s,4,%d", loc, idx), locs) } return tree.messages[key] }
func (fg *FileGenerator) GenerateOneofDefinition(prefix string, inMessage *descriptor.DescriptorProto, oneofIndex int) error { inOneof := inMessage.GetOneofDecl()[oneofIndex] // TODO: Prefix with message name to avoid collisions. oneofType := oneofType(inOneof) fg.P("") fg.P("") fg.P("type %s", oneofType) { fg.In() leading := "=" { oneofVariantName := oneofUnspecifiedValue(inOneof) fg.P("%s %s", leading, oneofVariantName) leading = "|" } for _, inField := range inMessage.GetField() { if inField.OneofIndex != nil && inField.GetOneofIndex() == int32(oneofIndex) { oneofVariantName := elmTypeName(inField.GetName()) oneofArgumentType := fieldElmType(inField) fg.P("%s %s %s", leading, oneofVariantName, oneofArgumentType) leading = "|" } } fg.Out() } return nil }
func (fg *FileGenerator) GenerateOneofDecoder(prefix string, inMessage *descriptor.DescriptorProto, oneofIndex int) error { inOneof := inMessage.GetOneofDecl()[oneofIndex] // TODO: Prefix with message name to avoid collisions. oneofType := oneofType(inOneof) decoderName := oneofDecoderName(inOneof) fg.P("") fg.P("") fg.P("%s : JD.Decoder %s", decoderName, oneofType) fg.P("%s =", decoderName) { fg.In() fg.P("JD.lazy <| \\_ -> JD.oneOf") { fg.In() leading := "[" for _, inField := range inMessage.GetField() { if inField.OneofIndex != nil && inField.GetOneofIndex() == int32(oneofIndex) { oneofVariantName := elmTypeName(inField.GetName()) decoderName := fieldDecoderName(inField) fg.P("%s JD.map %s (JD.field %q %s)", leading, oneofVariantName, inField.GetJsonName(), decoderName) leading = "," } } fg.P("%s JD.succeed %s", leading, oneofUnspecifiedValue(inOneof)) fg.P("]") fg.Out() } fg.Out() } return nil }
func convertMessageType(curPkg *ProtoPackage, msg *descriptor.DescriptorProto) (schema []*Field, err error) { if glog.V(4) { glog.Info("Converting message: ", proto.MarshalTextString(msg)) } for _, fieldDesc := range msg.GetField() { field, err := convertField(curPkg, fieldDesc, msg) if err != nil { glog.Errorf("Failed to convert field %s in %s: %v", fieldDesc.GetName(), msg.GetName(), err) return nil, err } schema = append(schema, field) } return }
func (fg *FileGenerator) GenerateMessageDefinition(prefix string, inMessage *descriptor.DescriptorProto) error { typeName := prefix + inMessage.GetName() fg.P("") fg.P("") fg.P("type alias %s =", typeName) { fg.In() leading := "{" for _, inField := range inMessage.GetField() { if inField.OneofIndex != nil { // Handled in the oneof only. continue } optional := (inField.GetLabel() == descriptor.FieldDescriptorProto_LABEL_OPTIONAL) && (inField.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE) repeated := inField.GetLabel() == descriptor.FieldDescriptorProto_LABEL_REPEATED fType := fieldElmType(inField) fName := elmFieldName(inField.GetName()) fNumber := inField.GetNumber() if repeated { fg.P("%s %s : List %s -- %d", leading, fName, fType, fNumber) } else { if optional { fg.P("%s %s : Maybe %s -- %d", leading, fName, fType, fNumber) } else { fg.P("%s %s : %s -- %d", leading, fName, fType, fNumber) } } leading = "," } for _, inOneof := range inMessage.GetOneofDecl() { oneofName := elmFieldName(inOneof.GetName()) // TODO: Prefix with message name to avoid collisions. oneofTypeName := elmTypeName(inOneof.GetName()) fg.P("%s %s : %s", leading, oneofName, oneofTypeName) leading = "," } fg.P("}") fg.Out() } for i, _ := range inMessage.GetOneofDecl() { fg.GenerateOneofDefinition(prefix, inMessage, i) fg.GenerateOneofDecoder(prefix, inMessage, i) fg.GenerateOneofEncoder(prefix, inMessage, i) } return nil }
func relativelyLookupNestedType(desc *descriptor.DescriptorProto, name string) (*descriptor.DescriptorProto, bool) { components := strings.Split(name, ".") componentLoop: for _, component := range components { for _, nested := range desc.GetNestedType() { if nested.GetName() == component { desc = nested continue componentLoop } } glog.Infof("no such nested message %s in %s", component, desc.GetName()) return nil, false } return desc, true }
func (fg *FileGenerator) GenerateEverything(prefix string, inMessage *descriptor.DescriptorProto) error { newPrefix := prefix + inMessage.GetName() + "_" var err error err = fg.GenerateMessageDefinition(prefix, inMessage) if err != nil { return err } for _, inEnum := range inMessage.GetEnumType() { err = fg.GenerateEnumDefinition(newPrefix, inEnum) if err != nil { return err } } err = fg.GenerateMessageDecoder(prefix, inMessage) if err != nil { return err } for _, inEnum := range inMessage.GetEnumType() { err = fg.GenerateEnumDecoder(newPrefix, inEnum) if err != nil { return err } } err = fg.GenerateMessageEncoder(prefix, inMessage) if err != nil { return err } for _, inEnum := range inMessage.GetEnumType() { err = fg.GenerateEnumEncoder(newPrefix, inEnum) if err != nil { return err } } // Nested messages. for _, nested := range inMessage.GetNestedType() { fg.GenerateEverything(newPrefix, nested) } return nil }
func (fg *FileGenerator) GenerateOneofEncoder(prefix string, inMessage *descriptor.DescriptorProto, oneofIndex int) error { inOneof := inMessage.GetOneofDecl()[oneofIndex] // TODO: Prefix with message name to avoid collisions. oneofType := oneofType(inOneof) encoderName := oneofEncoderName(inOneof) argName := "v" fg.P("") fg.P("") fg.P("%s : %s -> Maybe ( String, JE.Value )", encoderName, oneofType) fg.P("%s %s =", encoderName, argName) { fg.In() fg.P("case %s of", argName) { fg.In() valueName := "x" { oneofVariantName := oneofUnspecifiedValue(inOneof) fg.P("%s -> Nothing", oneofVariantName) } // TODO: Evaluate them in reverse order, as per // https://developers.google.com/protocol-buffers/docs/proto3#oneof for _, inField := range inMessage.GetField() { if inField.OneofIndex != nil && inField.GetOneofIndex() == int32(oneofIndex) { oneofVariantName := elmTypeName(inField.GetName()) e := fieldEncoderName(inField) fg.P("%s %s ->", oneofVariantName, valueName) fg.In() fg.P("Just ( %q, %s %s )", inField.GetJsonName(), e, valueName) fg.Out() } } fg.Out() } fg.Out() } return nil }
func registerType(pkgName *string, msg *descriptor.DescriptorProto) { pkg := globalPkg if pkgName != nil { for _, node := range strings.Split(*pkgName, ".") { if pkg == globalPkg && node == "" { // Skips leading "." continue } child, ok := pkg.children[node] if !ok { child = &ProtoPackage{ name: pkg.name + "." + node, parent: pkg, children: make(map[string]*ProtoPackage), types: make(map[string]*descriptor.DescriptorProto), } pkg.children[node] = child } pkg = child } } pkg.types[msg.GetName()] = msg }
func (fg *FileGenerator) GenerateMessageEncoder(prefix string, inMessage *descriptor.DescriptorProto) error { typeName := prefix + inMessage.GetName() argName := "v" fg.P("") fg.P("") fg.P("%s : %s -> JE.Value", encoderName(typeName), typeName) fg.P("%s %s =", encoderName(typeName), argName) { fg.In() fg.P("JE.object <| List.filterMap identity <|") { fg.In() leading := "[" for _, inField := range inMessage.GetField() { if inField.OneofIndex != nil { // Handled in the oneof only. continue } optional := (inField.GetLabel() == descriptor.FieldDescriptorProto_LABEL_OPTIONAL) && (inField.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE) repeated := inField.GetLabel() == descriptor.FieldDescriptorProto_LABEL_REPEATED d := fieldEncoderName(inField) val := argName + "." + elmFieldName(inField.GetName()) def := fieldDefaultValue(inField) if repeated { fg.P("%s (repeatedFieldEncoder %q %s %s)", leading, jsonFieldName(inField), d, val) } else { if optional { fg.P("%s (optionalEncoder %q %s %s)", leading, jsonFieldName(inField), d, val) } else { fg.P("%s (requiredFieldEncoder %q %s %s %s)", leading, jsonFieldName(inField), d, def, val) } } leading = "," } for _, inOneof := range inMessage.GetOneofDecl() { val := argName + "." + elmFieldName(inOneof.GetName()) oneofEncoderName := oneofEncoderName(inOneof) fg.P("%s (%s %s)", leading, oneofEncoderName, val) leading = "," } fg.P("]") fg.Out() } fg.Out() } return nil }
func (fg *FileGenerator) GenerateMessageDecoder(prefix string, inMessage *descriptor.DescriptorProto) error { typeName := prefix + inMessage.GetName() fg.P("") fg.P("") fg.P("%s : JD.Decoder %s", decoderName(typeName), typeName) fg.P("%s =", decoderName(typeName)) { fg.In() fg.P("JD.lazy <| \\_ -> %s", typeName) { fg.In() leading := "<$>" for _, inField := range inMessage.GetField() { if inField.OneofIndex != nil { // Handled in the oneof only. continue } optional := (inField.GetLabel() == descriptor.FieldDescriptorProto_LABEL_OPTIONAL) && (inField.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE) repeated := inField.GetLabel() == descriptor.FieldDescriptorProto_LABEL_REPEATED d := fieldDecoderName(inField) def := fieldDefaultValue(inField) if repeated { fg.P("%s (repeatedFieldDecoder %q %s)", leading, jsonFieldName(inField), d) } else { if optional { fg.P("%s (optionalFieldDecoder %q %s)", leading, jsonFieldName(inField), d) } else { fg.P("%s (requiredFieldDecoder %q %s %s)", leading, jsonFieldName(inField), def, d) } } leading = "<*>" } for _, inOneof := range inMessage.GetOneofDecl() { oneofDecoderName := oneofDecoderName(inOneof) fg.P("%s %s", leading, oneofDecoderName) leading = "<*>" } fg.Out() } fg.Out() } return nil }