func main() {
	// Begin by allocating a generator. The request and response structures are stored there
	// so we can do error handling easily - the response structure contains the field to
	// report failure.
	g := generator.New()

	data, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		g.Error(err, "reading input")
	}

	if err := proto.Unmarshal(data, g.Request); err != nil {
		g.Error(err, "parsing input proto")
	}

	// generator处理数命令行参数(?)
	if len(g.Request.FileToGenerate) == 0 {
		g.Fail("no files to generate")
	}

	g.CommandLineParameters(g.Request.GetParameter())

	// Create a wrapped version of the Descriptors and EnumDescriptors that
	// point to the file that defines them.
	g.WrapTypes()

	g.SetPackageNames()
	g.BuildTypeNameMap()

	g.GenerateAllFiles()

	// Send back the results.
	data, err = proto.Marshal(g.Response)
	if err != nil {
		g.Error(err, "failed to marshal output proto")
	}
	_, err = os.Stdout.Write(data)
	if err != nil {
		g.Error(err, "failed to write output proto")
	}
}
Exemple #2
0
func main() {
	// Begin by allocating a generator. The request and response structures are stored there
	// so we can do error handling easily - the response structure contains the field to
	// report failure.
	str := `{"cmd_name":"Pmd.UserJsMessageForwardUserPmd_CS","msg":{"errno":"0","st":1470339434,"data":{"ret":0,"uid":1126119,"errno":"0","userInfo":{"roundNum":41,"signature":"","gender":"男","giftCoupon":0,"nickName":"1126119","headUrl":"http:\/\/1251210123.cdn.myqcloud.com\/1251210123\/QZONESTATIC\/headImages\/97.jpg","uid":1126119,"remainder":17187041,"maxMulti":59,"sumRecharge":0,"platId":0,"subPlatId":0,"bankChips":0},"gmLevel":0,"roomInfo":[{"lowestCarry":1,"maxSeat":20,"bankerConfig":{"selectChips":[3000000,5000000,8000000,10000000],"lowestBankerChips":3000000},"lowestBet":100,"roomName":"房间10002","roomId":10002,"maxUser":10000},{"lowestCarry":500000,"maxSeat":20,"bankerConfig":{"selectChips":[30000000,50000000,80000000,100000000],"lowestBankerChips":30000000},"lowestBet":100,"roomName":"房间10004","roomId":10004,"maxUser":10000}]},"do":"Cmd.UserInfoSynRequestLobbyCmd_S"}}`
	var jsmap map[string]interface{}
	err1 := json.Unmarshal([]byte(str), &jsmap)
	if err1 != nil {
		fmt.Println(err1)
	}
	proto.MarshalMessageSetJSON
	g := generator.New()

	file, er := os.Open("/tmp/pmd.pb")
	if er != nil {
		g.Error(er, "reading input")
	}
	data, err := ioutil.ReadAll(file)
	if err != nil {
		g.Error(err, "reading input")
	}

	if err := proto.Unmarshal(data, g.Request); err != nil {
		g.Error(err, "parsing input proto")
	}

	if len(g.Request.FileToGenerate) == 0 {
		g.Fail("no files to generate")
	}
	fmt.Println(g.Request.ProtoFile)
	fmt.Println(g.Request.FileToGenerate)
	//g.Request.FileToGenerate[0] = "pmd.proto"
	//g.Request.FileToGenerate = append(g.Request.FileToGenerate, "pmd.proto")
	//fmt.Println(g.Request.FileToGenerate[0])
	//fmt.Println(g.Request.Parameter)
	//fmt.Println(g.Request.ProtoFile)
	//fmt.Println(g.Request.XXX_unrecognized)

	//g.CommandLineParameters(g.Request.GetParameter())

	// Create a wrapped version of the Descriptors and EnumDescriptors that
	// point to the file that defines them.
	//g.WrapTypes()
	fmt.Println("XXXXXXXXXXXXXXXXXXXXX")

	//g.SetPackageNames()
	fmt.Println("XXXXXXXXXXXXXXXXXXXXX")
	//g.BuildTypeNameMap()

	//g.GenerateAllFiles()

	// Send back the results.
	data, err = proto.Marshal(g.Response)
	//if err != nil {
	//	g.Error(err, "failed to marshal output proto")
	//}
	//_, err = os.Stdout.Write(data)
	if err != nil {
		g.Error(err, "failed to write output proto")
	}
	//file.Write(data)
	file.Close()
}
Exemple #3
0
// Read from standard input
func main() {
	g := generator.New()

	data, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		failWithError(err, "reading input")
	}

	if err := proto.Unmarshal(data, g.Request); err != nil {
		failWithError(err, "parsing input proto")
	}

	if len(g.Request.FileToGenerate) == 0 {
		fail("no files to generate")
	}

	g.CommandLineParameters(g.Request.GetParameter())

	if val, ok := g.Param["logtostderr"]; ok && val == "true" {
		logtostderr = true
	}

	tree := buildTree(g.Request.GetProtoFile())

	packageLocations := make(map[string]string)
	for _, file := range g.Request.GetProtoFile() {
		loc := file.GetName()[:strings.LastIndex(file.GetName(), "/")]
		packageLocations[file.GetPackage()] = loc
	}

	selectedServices := make(map[string]string)
	for k, v := range g.Param {
		switch {
		case k == "logtostderr":
			if v == "true" {
				logtostderr = true
			}
		case strings.HasPrefix(k, "."):
			selectedServices[k] = v
		}
	}

	for serviceKey := range selectedServices {
		service, ok := tree.services[serviceKey]
		if !ok {
			fail("Service", serviceKey, "unknown")
		}

		usedMessages := make(map[string]*message)
		usedEnums := make(map[string]*enum)

		content := new(bytes.Buffer)

		fmt.Fprintf(content, "# %s API Reference\n\n", service.GetName())
		if service.comment != "" {
			fmt.Fprintf(content, "%s\n\n", service.comment)
		}

		if len(service.methods) > 0 {
			fmt.Fprint(content, "## Methods\n\n")

			for _, method := range service.methods {
				fmt.Fprintf(content, "### `%s`\n\n", method.GetName())
				if method.comment != "" {
					fmt.Fprintf(content, "%s\n\n", method.comment)
				}
				if method.inputStream {
					fmt.Fprintf(content, "- Client stream of [`%s`](#%s)\n", method.input.GetName(), heading(method.input.key))
				} else {
					fmt.Fprintf(content, "- Request: [`%s`](#%s)\n", method.input.GetName(), heading(method.input.key))
				}
				useMessage(tree, method.input, usedMessages, usedEnums)
				if method.outputStream {
					fmt.Fprintf(content, "- Server stream of [`%s`](#%s)\n", method.output.GetName(), heading(method.input.key))
				} else {
					fmt.Fprintf(content, "- Response: [`%s`](#%s)\n", method.output.GetName(), heading(method.input.key))
				}
				useMessage(tree, method.output, usedMessages, usedEnums)

				fmt.Fprintln(content)

				if len(method.endpoints) != 0 {
					if len(method.endpoints) == 1 {
						fmt.Fprint(content, "#### HTTP Endpoint\n\n")
					} else {
						fmt.Fprint(content, "#### HTTP Endpoints\n\n")
					}
					for _, endpoint := range method.endpoints {
						fmt.Fprintf(content, "- `%s` `%s`", endpoint.method, endpoint.url)
						var params []string
						for _, match := range regexp.MustCompile(`\{([a-z_]+)\}`).FindAllStringSubmatch(endpoint.url, -1) {
							if match != nil && len(match) == 2 && match[1] != "" {
								params = append(params, fmt.Sprintf("`%s`", match[1]))
							}
						}
						if len(params) > 0 {
							fmt.Fprintf(content, "(%s can be left out of the request body)", strings.Join(params, ", "))
						}
						fmt.Fprintln(content)
					}
					fmt.Fprintln(content)

					fmt.Fprint(content, "#### JSON Request Format\n\n")
					fmt.Fprintf(content, "```json\n%s\n```\n\n", method.input.JSONExample(tree))

					fmt.Fprint(content, "#### JSON Response Format\n\n")
					fmt.Fprintf(content, "```json\n%s\n```\n\n", method.output.JSONExample(tree))
				}
			}
		}

		if len(usedMessages) > 0 {
			fmt.Fprint(content, "## Messages\n\n")

			var messageKeys []string
			for key := range usedMessages {
				messageKeys = append(messageKeys, key)
			}
			sort.Strings(messageKeys)

			for _, messageKey := range messageKeys {
				message := usedMessages[messageKey]
				fmt.Fprintf(content, "### `%s`\n\n", message.key)
				if strings.HasPrefix(messageKey, ".google") {
					fmt.Fprintf(content, "%s\n\n", strings.SplitAfter(message.comment, ".")[0])
				} else if message.comment != "" {
					fmt.Fprintf(content, "%s\n\n", message.comment)
				}
				if len(message.fields) > 0 {
					fmt.Fprintln(content, "| Field Name | Type | Description |")
					fmt.Fprintln(content, "| ---------- | ---- | ----------- |")
					for idx, field := range message.fields {
						if field.isOneOf {
							if idx == 0 || !message.fields[idx-1].isOneOf || message.fields[idx-1].GetOneofIndex() != field.GetOneofIndex() {
								oneof := message.GetOneof(field.GetOneofIndex())
								if len(oneof.fields) > 1 {
									fmt.Fprintf(content, "| **%s** | **oneof %d** | one of the following %d |\n", oneof.GetName(), len(oneof.fields), len(oneof.fields))
								}
							}
						} else {
							if idx > 0 && message.fields[idx-1].isOneOf {
								oneof := message.GetOneof(message.fields[idx-1].GetOneofIndex())
								if len(oneof.fields) > 1 {
									fmt.Fprintf(content, "| **%s** | **end oneof %d** |  |\n", oneof.GetName(), len(oneof.fields))
								}
							}
						}

						var fieldType string
						if field.repeated {
							fieldType += "_repeated_ "
						}
						typ := strings.ToLower(strings.TrimPrefix(field.GetType().String(), "TYPE_"))
						switch typ {
						case "message":
							friendlyType := field.GetTypeName()[strings.LastIndex(field.GetTypeName(), ".")+1:]
							fieldType += fmt.Sprintf("[`%s`](#%s)", friendlyType, heading(field.GetTypeName()))
						case "enum":
							// TODO(htdvisser): test this
							if enum, ok := tree.enums[field.GetTypeName()]; ok {
								usedEnums[field.GetTypeName()] = enum
							}
							friendlyType := field.GetTypeName()[strings.LastIndex(field.GetTypeName(), ".")+1:]
							fieldType += fmt.Sprintf("[`%s`](#%s)", friendlyType, heading(field.GetTypeName()))
						default:
							fieldType += fmt.Sprintf("`%s`", typ)
						}
						fmt.Fprintf(content, "| `%s` | %s | %s |\n", field.GetName(), fieldType, strings.Replace(field.comment, "\n", " ", -1))
					}
					fmt.Fprintln(content)
				}
			}
		}

		if len(usedEnums) > 0 {
			fmt.Fprint(content, "## Used Enums\n\n")

			var enumKeys []string
			for key := range usedEnums {
				enumKeys = append(enumKeys, key)
			}
			sort.Strings(enumKeys)

			for _, enumKey := range enumKeys {
				enum := usedEnums[enumKey]

				fmt.Fprintf(content, "### `%s`\n\n", enum.key)
				if enum.comment != "" {
					fmt.Fprintf(content, "%s\n\n", enum.comment)
				}

				if len(enum.values) > 0 {
					fmt.Fprintln(content, "| Value | Description |")
					fmt.Fprintln(content, "| ----- | ----------- |")
					for _, value := range enum.values {
						fmt.Fprintf(content, "| `%s` | %s |\n", value.GetName(), strings.Replace(value.comment, "\n", " ", -1))
					}
					fmt.Fprintln(content)
				}
			}
		}

		packageService := strings.TrimPrefix(service.key, ".")
		packageName := packageService[:strings.Index(packageService, ".")]
		location, ok := packageLocations[packageName]
		if !ok {
			fail("Could not find location of package", packageName)
		}
		fileName := path.Join(location, service.GetName()+".md")
		contentString := content.String()
		g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{
			Name:    &fileName,
			Content: &contentString,
		})
	}

	// Send back the results.
	data, err = proto.Marshal(g.Response)
	if err != nil {
		failWithError(err, "failed to marshal output proto")
	}
	_, err = os.Stdout.Write(data)
	if err != nil {
		failWithError(err, "failed to write output proto")
	}
}