Exemple #1
0
// FormatNode writes e, formatted almost like a protobuf message, to w.
func FormatNode(w io.Writer, e *yang.Entry) {
	fmt.Fprintln(w)
	if e.Description != "" {
		fmt.Fprintln(indent.NewWriter(w, "// "), e.Description)
	}
	fmt.Fprintf(w, "message %s {\n", fixName(e.Name))

	var names []string
	for k := range e.Dir {
		names = append(names, k)
	}
	sort.Strings(names)
	for x, k := range names {
		se := e.Dir[k]
		if se.Description != "" {
			fmt.Fprintln(indent.NewWriter(w, "  // "), se.Description)
		}
		if se.IsList {
			fmt.Fprint(w, "  repeated ")
		} else {
			fmt.Fprint(w, "  optional ")
		}
		if len(se.Dir) == 0 && se.Type != nil {
			// TODO(borman): this is probably an empty container.
			kind := "UNKNOWN TYPE"
			if se.Type != nil {
				kind = kind2proto[se.Type.Kind]
			}
			fmt.Fprintf(w, "%s %s = %d; // %s\n", kind, fixName(k), x+1, yang.Source(se.Node))
			continue
		}
		fmt.Fprintf(w, "%s %s = %d; // %s\n", fixName(se.Name), fixName(k), x+1, yang.Source(se.Node))
	}
	// { to match the brace below to keep brace matching working
	fmt.Fprintln(w, "}")
}
Exemple #2
0
// printType prints type t in a moderately human readable format to w.
func printType(w io.Writer, t *yang.YangType, verbose bool) {
	if verbose && t.Base != nil {
		base := yang.Source(t.Base)
		if base == "unknown" {
			base = "unnamed type"
		}
		fmt.Fprintf(w, "%s: ", base)
	}
	fmt.Fprintf(w, "%s", t.Root.Name)
	if t.Kind.String() != t.Root.Name {
		fmt.Fprintf(w, "(%s)", t.Kind)
	}
	if t.Units != "" {
		fmt.Fprintf(w, " units=%s", t.Units)
	}
	if t.Default != "" {
		fmt.Fprintf(w, " default=%q", t.Default)
	}
	if t.FractionDigits != 0 {
		fmt.Fprintf(w, " fraction-digits=%d", t.FractionDigits)
	}
	if len(t.Length) > 0 {
		fmt.Fprintf(w, " length=%s", t.Length)
	}
	if t.Kind == yang.YinstanceIdentifier && !t.OptionalInstance {
		fmt.Fprintf(w, " required")
	}
	if t.Kind == yang.Yleafref && t.Path != "" {
		fmt.Fprintf(w, " path=%q", t.Path)
	}
	if len(t.Pattern) > 0 {
		fmt.Fprintf(w, " pattern=%s", strings.Join(t.Pattern, "|"))
	}
	b := yang.BaseTypedefs[t.Kind.String()].YangType
	if len(t.Range) > 0 && !t.Range.Equal(b.Range) {
		fmt.Fprintf(w, " range=%s", t.Range)
	}
	if len(t.Type) > 0 {
		fmt.Fprintf(w, "union{\n")
		for _, t := range t.Type {
			printType(indent.NewWriter(w, "  "), t, verbose)
		}
		fmt.Fprintf(w, "}")
	}
	fmt.Fprintf(w, ";\n")
}
Exemple #3
0
// YTPrint prints type t in a moderately human readable format to w.
func YTPrint(w io.Writer, t *yang.YangType) {
	if t.Base != nil {
		fmt.Fprintf(w, "%s: ", yang.Source(t.Base))
	}
	fmt.Fprintf(w, "%s", t.Root.Name)
	if t.Kind.String() != t.Root.Name {
		fmt.Fprintf(w, "(%s)", t.Kind)
	}
	if t.Units != "" {
		fmt.Fprintf(w, " units=%s", t.Units)
	}
	if t.Default != "" {
		fmt.Fprintf(w, " default=%q", t.Default)
	}
	if t.FractionDigits != 0 {
		fmt.Fprintf(w, " fraction-digits=%d", t.FractionDigits)
	}
	if len(t.Length) > 0 {
		fmt.Fprintf(w, " length=%s", t.Length)
	}
	if t.Kind == yang.YinstanceIdentifier && !t.OptionalInstance {
		fmt.Fprintf(w, " required")
	}
	if t.Kind == yang.Yleafref && t.Path != "" {
		fmt.Fprintf(w, " path=%q", t.Path)
	}
	if len(t.Pattern) > 0 {
		fmt.Fprintf(w, " pattern=%s", strings.Join(t.Pattern, "|"))
	}
	if len(t.Type) > 0 {
		fmt.Fprintf(w, " union...")
	}

	b := yang.BaseTypedefs[t.Kind.String()].YangType
	if len(t.Range) > 0 && !t.Range.Equal(b.Range) {
		fmt.Fprintf(w, " range=%s", t.Range)
	}
	fmt.Fprintf(w, ";\n")
}
Exemple #4
0
// FormatNode writes e, formatted almost like a protobuf message, to w.
func FormatNode(w io.Writer, e *yang.Entry) {
	var names []string

	for k, se := range e.Dir {
		if se.RPC != nil {
			names = append(names, k)
		}
	}
	needEmpty := false
	if len(names) > 0 {
		sort.Strings(names)
		fmt.Fprintf(w, "service %s {\n", fixName(e.Name))
		for _, k := range names {
			rpc := e.Dir[k].RPC
			k = fixName(k)
			iName := "Empty"
			oName := "Empty"
			if rpc.Input != nil {
				iName = k + "Request"
				rpc.Input.Name = iName
				if isStream(rpc.Input) {
					iName = "stream " + iName
				}
			}
			if rpc.Output != nil {
				oName = k + "Response"
				rpc.Output.Name = oName
				if isStream(rpc.Output) {
					oName = "stream " + oName
				}
			}
			needEmpty = needEmpty || rpc.Input == nil || rpc.Output == nil
			fmt.Fprintf(w, "  rpc %s (%s) returns (%s);\n", k, iName, oName)
		}
		fmt.Fprintln(w, "}")
		for _, k := range names {
			rpc := e.Dir[k].RPC
			if rpc.Input != nil {
				FormatNode(w, rpc.Input)
			}
			if rpc.Output != nil {
				FormatNode(w, rpc.Output)
			}
		}
	}

	if needEmpty {
		fmt.Fprintln(w, "\nmessage Empty { }")
	}

	names = nil
	for k, se := range e.Dir {
		if se.RPC == nil {
			names = append(names, k)
		}
	}
	if len(names) == 0 {
		return
	}

	fmt.Fprintln(w)
	if e.Description != "" {
		fmt.Fprintln(indent.NewWriter(w, "// "), e.Description)
	}
	fmt.Fprintf(w, "message %s {\n", fixName(e.Name))

	sort.Strings(names)
	for x, k := range names {
		se := e.Dir[k]
		if se.Description != "" {
			fmt.Fprintln(indent.NewWriter(w, "  // "), se.Description)
		}
		if se.ListAttr != nil {
			fmt.Fprint(w, "  repeated ")
		} else {
			fmt.Fprint(w, "  optional ")
		}
		if len(se.Dir) == 0 && se.Type != nil {
			// TODO(borman): this is probably an empty container.
			kind := "UNKNOWN TYPE"
			if se.Type != nil {
				kind = kind2proto[se.Type.Kind]
			}
			fmt.Fprintf(w, "%s %s = %d; // %s\n", kind, fixName(k), x+1, yang.Source(se.Node))
			continue
		}
		fmt.Fprintf(w, "%s %s = %d; // %s\n", fixName(se.Name), fixName(k), x+1, yang.Source(se.Node))
	}
	// { to match the brace below to keep brace matching working
	fmt.Fprintln(w, "}")
}
Exemple #5
0
// printNode writes e, formatted almost like a protobuf message, to w.
func (pf *protofile) printNode(w io.Writer, e *yang.Entry, nest bool) {
	nodes := children(e)

	if !protoNoComments && e.Description != "" {
		fmt.Fprintln(indent.NewWriter(w, "// "), e.Description)
	}

	messageName := pf.fullName(e)
	mi := pf.messages[messageName]
	if mi == nil {
		mi = &messageInfo{
			fields: map[string]int{},
		}
		pf.messages[messageName] = mi
	}

	fmt.Fprintf(w, "message %s {", pf.messageName(e)) // matching brace }
	if protoWithSource {
		fmt.Fprintf(w, " // %s", yang.Source(e.Node))
	}
	fmt.Fprintln(w)

	for i, se := range nodes {
		k := se.Name
		if !protoNoComments && se.Description != "" {
			fmt.Fprintln(indent.NewWriter(w, "  // "), se.Description)
		}
		if nest && (len(se.Dir) > 0 || se.Type == nil) {
			pf.printNode(indent.NewWriter(w, "  "), se, true)
		}
		prefix := "  "
		if se.ListAttr != nil {
			prefix = "  repeated "
		} else if proto2 {
			prefix = "  optional "
		}
		name := pf.fieldName(k)
		printed := false
		var kind string
		if len(se.Dir) > 0 || se.Type == nil {
			kind = pf.messageName(se)
		} else if se.Type.Kind == yang.Ybits {
			values := dedup(se.Type.Bit.Values())
			asComment := false
			switch {
			case len(values) > 0 && values[len(values)-1] > 63:
				if i != 0 {
					fmt.Fprintln(w)
				}
				fmt.Fprintf(w, "  // *WARNING* bitfield %s has more than 64 positions\n", name)
				kind = "uint64"
				asComment = true
			case len(values) > 0 && values[len(values)-1] > 31:
				if i != 0 {
					fmt.Fprintln(w)
				}
				fmt.Fprintf(w, "  // bitfield %s to large for enum\n", name)
				kind = "uint64"
				asComment = true
			default:
				kind = pf.fixName(se.Name)
			}
			if !asComment {
				fmt.Fprintf(w, "  enum %s {\n", kind)
				fmt.Fprintf(w, "    %s_FIELD_NOT_SET = 0;\n", kind)
			} else {
				fmt.Fprintf(w, "  // Values:\n")
			}
			names := map[int64][]string{}
			for n, v := range se.Type.Bit.NameMap() {
				names[v] = append(names[v], n)
			}
			for _, v := range values {
				ns := names[v]
				sort.Strings(ns)
				if asComment {
					for _, n := range ns {
						fmt.Fprintf(w, "  //   %s = 1 << %d\n", n, v)
					}
				} else {
					n := strings.ToUpper(pf.fieldName(ns[0]))
					fmt.Fprintf(w, "    %s_%s = %d;\n", kind, n, 1<<uint(v))
					for _, n := range ns[1:] {
						n = strings.ToUpper(pf.fieldName(n))
						fmt.Fprintf(w, "    // %s = %d; (DUPLICATE VALUE)\n", n, 1<<uint(v))
					}
				}
			}
			if !asComment {
				fmt.Fprintf(w, "  };\n")
			}
		} else if se.Type.Kind == yang.Ydecimal64 {
			kind = "Decimal64"
			pf.hasDecimal64 = true
		} else if se.Type.Kind == yang.Yenum {
			kind = pf.fixName(se.Name)
			fmt.Fprintf(w, "  enum %s {", kind)
			if protoWithSource {
				fmt.Fprintf(w, " // %s", yang.Source(se.Node))
			}
			fmt.Fprintln(w)

			for i, n := range se.Type.Enum.Names() {
				fmt.Fprintf(w, "    %s_%s = %d;\n", kind, strings.ToUpper(pf.fieldName(n)), i)
			}
			fmt.Fprintf(w, "  };\n")
		} else if se.Type.Kind == yang.Yunion {
			types := pf.unionTypes(se.Type, map[string]bool{})
			switch len(types) {
			case 0:
				fmt.Fprintf(w, "    // *WARNING* union %s has no types\n", se.Name)
				printed = true
			case 1:
				kind = types[0]
			default:
				iw := w
				kind = pf.fixName(se.Name)
				if se.ListAttr != nil {
					fmt.Fprintf(w, "  message %s {\n", kind)
					iw = indent.NewWriter(w, "  ")
				}
				fmt.Fprintf(iw, "  oneof %s {", kind) // matching brace }
				if protoWithSource {
					fmt.Fprintf(w, " // %s", yang.Source(se.Node))
				}
				fmt.Fprintln(w)
				for _, tkind := range types {
					fmt.Fprintf(iw, "    %s %s_%s = %d;\n", tkind, kind, tkind, mi.tag(name, tkind, false))
				}
				// { to match the brace below to keep brace matching working
				fmt.Fprintf(iw, "  }\n")
				if se.ListAttr != nil {
					fmt.Fprintf(w, "  }\n")
				} else {
					printed = true
				}
			}
		} else {
			kind = kind2proto[se.Type.Kind]
		}
		if !printed {
			fmt.Fprintf(w, "%s%s %s = %d;", prefix, kind, name, mi.tag(name, kind, se.ListAttr != nil))
			if protoWithSource {
				fmt.Fprintf(w, " // %s", yang.Source(se.Node))
			}
			fmt.Fprintln(w)
		}
	}
	// { to match the brace below to keep brace matching working
	fmt.Fprintln(w, "}")
}