xuri / xgen

XSD (XML Schema Definition) parser and Go/C/Java/Rust/TypeScript code generator
BSD 3-Clause "New" or "Revised" License
339 stars 80 forks source link

Go: infinite self-referencing type generated for embedded simpleType with base restriction #48

Open dziewas opened 2 years ago

dziewas commented 2 years ago

Description

When element's type is embedded as a child simpleType and has a base restriction then the Go code contains self-referencing type definition that causes infinite loop in xml marshalling.

Steps to reproduce the issue:

  1. For the xsd file like this one:

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="header">
        <xs:sequence>
            <xs:element name="operation">
                <xs:simpleType>
                    <xs:restriction base="operationCode"/>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    <xs:simpleType name="operationCode">
        <xs:restriction base="xs:string">
            <xs:length value="3"/>
        </xs:restriction>
    </xs:simpleType>
    </xs:schema>
  2. Run:

    xgen -i xsd/op.xsd -p schema -o output -l Go
  3. The following model is generated:

    
    // Code generated by xgen. DO NOT EDIT.

package schema

import ( "encoding/xml" )

// Header ... type Header struct { XMLName xml.Name xml:"header" Operation *Operation xml:"operation" }

// Operation ... type Operation *Operation

// OperationCode ... type OperationCode string


4. And this goes into infinite loop:
```go
package main

import (
    "encoding/xml"
    "os"

    schema "github.com/xuri/xgen/data/output"
)

func main() {
    xml.NewEncoder(os.Stdout).Encode(&schema.Header{})
}

Describe the results you received:

// Code generated by xgen. DO NOT EDIT.

package schema

import (
    "encoding/xml"
)

// Header ...
type Header struct {
    XMLName   xml.Name   `xml:"header"`
    Operation *Operation `xml:"operation"`
}

// Operation ...
type Operation *Operation

// OperationCode ...
type OperationCode string

Describe the results you expected:

// Code generated by xgen. DO NOT EDIT.

package schema

import (
    "encoding/xml"
)

// Header ...
type Header struct {
    XMLName   xml.Name       `xml:"header"`
    Operation *OperationCode `xml:"operation"`
}

// OperationCode ...
type OperationCode string

Output of go version:

xgen version: 0.1.0

xgen version or commit ID:

2afb9de (HEAD -> master, origin/master, origin/HEAD) Upgrade GitHub Actions workflow toolchain version

Environment details (OS, physical, etc.):

$ uname -a
Linux thinkpad 5.13.0-39-generic #44~20.04.1-Ubuntu SMP Thu Mar 24 16:43:35 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/marcin/.cache/go-build"
GOENV="/home/marcin/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/marcin/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/marcin/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/marcin/.local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/marcin/.local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.3"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/marcin/projects/xgen/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1566108439=/tmp/go-build -gno-record-gcc-switches"